当前位置: 首页 > 知识库问答 >
问题:

使用查询DSL在数据库中查询近距离点

邓德惠
2023-03-14

我的申请中有以下实体:

  • 会员
  • 家庭广告
  • 地址

成员实体中:

@OneToOne(cascade=CascadeType.ALL)
    private Address address;
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "member")
private List<Advertisement> advertisements;

在< code >广告实体中:

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
private Member member;

完整地址实体:

@Entity
public class Address {

    private String formattedAddress;
    private double latitude;
    private double longitude;
}

我想找到所有的家庭广告实例,其成员的地址在所需地址的20KM以内。

以下是我得出的结论:

QFamilyAdvertisement qFamilyAdvertisement = QFamilyAdvertisement.familyAdvertisement;

NumberPath<Double> lat = qFamilyAdvertisement.member.address.latitude;//NPE
NumberPath<Double> lng = qFamilyAdvertisement.member.address.longitude;
NumberPath<Double> distance = null;
NumberExpression<Double> formula = 
        (acos(cos(radians(Expressions.constant(requiredAddress.getLatitude())))
        .multiply(cos(radians(lat))
        .multiply(cos(radians(lng).subtract(radians(Expressions.constant(requiredAddress.getLongitude())))
        .add(sin(radians(Expressions.constant(requiredAddress.getLatitude())))
        .multiply(sin(radians(lat))))))))
        .multiply(Expressions.constant(6371)));

List<FamilyAdvertisement> foundFamilyAdvertisements = from(qFamilyAdvertisement.member.address).where(formula.as(distance).lt(20)).list(qFamilyAdvertisement);

但是,似乎我错误地使用了数字路径类,因为我不断得到一个NPE。任何人都可以帮我正确查询吗?

编辑:我已经改变了我的家庭广告实体如下:

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@QueryInit("address")
private Member member;

我现在得到以下异常:

java.lang.IllegalArgumentException: Only root paths are allowed for joins : familyAdvertisement.member.address
    com.mysema.query.DefaultQueryMetadata.ensureRoot(DefaultQueryMetadata.java:208)
    com.mysema.query.DefaultQueryMetadata.validateJoin(DefaultQueryMetadata.java:132)
    com.mysema.query.DefaultQueryMetadata.addJoin(DefaultQueryMetadata.java:118)
    com.mysema.query.DefaultQueryMetadata.addJoin(DefaultQueryMetadata.java:110)
    com.mysema.query.support.QueryMixin.from(QueryMixin.java:161)
    com.mysema.query.jpa.JPQLQueryBase.from(JPQLQueryBase.java:96)
    com.mysema.query.jpa.impl.JPAQuery.from(JPAQuery.java:30)
    org.springframework.data.jpa.repository.support.Querydsl.createQuery(Querydsl.java:88)
    org.springframework.data.jpa.repository.support.QueryDslRepositorySupport.from(QueryDslRepositorySupport.java:94)
    com.bignibou.repository.FamilyAdvertisementRepositoryImpl.performFamilyAdvertisementSearch(FamilyAdvertisementRepositoryImpl.java:64)

第64行是这样的:

List<FamilyAdvertisement> foundFamilyAdvertisements = from(qFamilyAdvertisement.member.address).where(formula.as(distance).lt(20)).list(qFamilyAdvertisement);

任何线索现在出了什么问题?

edit2:我忘了提到< code>FamilyAdvertisement扩展了< code>Advertisement,并且< code>member变量在< code>Advertisement中。

edit3:下面是我试图用QueryDSL重现的SQL:

select * from family_advertisement a inner join member m
on a.member = m.id
where m.address
in (
SELECT id 
FROM address where 
 6371 * 
acos( cos( radians(48.8558966) ) 
* cos( radians( latitude ) ) 
* cos( radians( longitude ) - radians(2.3622728) ) 
+ sin( radians(48.8558966) )
* sin( radians( latitude ) )
) < 20);

我试过这样的东西:

List<FamilyAdvertisement> foundFamilyAdvertisements = from(qFamilyAdvertisement).where(qFamilyAdvertisement.member.address.in(

                new JPASubQuery().from(QAddress.address).where(formula.lt(20)))

                ).list(qFamilyAdvertisement);

上面给出了公式,但我不确定如何在QueryDSL中表达不相关的子查询,尤其是上面的in运算符似乎有问题…

编辑4:

以下子查询现在有效:

List<FamilyAdvertisement> foundFamilyAdvertisements = 
        from(qFamilyAdvertisement).where(qFamilyAdvertisement.member.address.in(new JPASubQuery().from(QAddress.address).where(formula.lt(20)).list(QAddress.address))).list(qFamilyAdvertisement);

共有1个答案

澹台俊材
2023-03-14

这个路径对于急切的初始化来说太长了

qFamilyAdvertisement.member.address.latitude;

请在此处阅读有关查询 http://www.querydsl.com/static/querydsl/3.1.0/reference/html/ch03s04.html#d0e1699 中路径初始化的更多信息

 类似资料:
  • 距离查询 距离查询,是指查询指定几何对象一定距离范围内的地物。对于点几何对象,则查询以该点为圆心,以距离为半径画圆,落在该圆形范围内的地物;对于线和面几何对象,则查询距离对象边界一定范围内的地物。 以 World 数据服务为例。使用接口 ol.supermap.QueryService 在图层 “Capitals@World.1” 中查找距离指定点为10度(地图坐标单位)的矢量要素。 // 添加查

  • 问题内容: 选项 询问 我有一个包含4列的数据库表: 唯一身份 城市名 纬度(纬度) 经度(lng) 我在顶部使用查询返回距指定坐标距离指定英里数内的位置。它似乎可行,但我不确定它的准确性如何。我很想知道查询是否很好,或者您是否有更好的解决方案。 问题答案: 看起来像是正确的大圆距查询。 您对WRT的准确性有何看法?

  • 问题内容: 我必须查询成千上万个条目的数据库,并按距指定点的距离对其进行排序。 问题是每个条目都有一个纬度和经度,我需要检索每个条目以计算其距离。对于大型数据库,我不想检索每一行,这可能需要一些时间。 有什么办法可以将其构建到mysql查询中,以便我只需要检索最近的15个条目。 例如 问题答案: 选项1:通过切换到支持GeoIP的数据库对数据库进行计算。 选项2:使用如下存储过程对数据库进行计算:

  • 问题内容: 我正在寻找一种借助Elasticsearch查找最近价格/数量的可能性。问题是我没有范围。我要实现的是,结果按最近距离排序。根据示例搜索查询,我的索引包含3个具有以下价格(数字)的文档:45、27、32 给定数字与我的搜索值29的“距离”为45-29 = 16 | 27-29 = -2 | 32-29 = 3,所以我希望搜索结果是按“距离”评分的,该数字距离给定价格不远。 搜索查询示例

  • 主要内容:匹配所有查询,全文查询,匹配查询,multi_match查询,查询字符串查询,期限等级查询,范围查询,复合查询,连接查询,地理查询在Elasticsearch中,通过使用基于JSON的查询进行搜索。 查询由两个子句组成 - 叶查询子句 - 这些子句是匹配,项或范围的,它们在特定字段中查找特定值。 复合查询子句 - 这些查询是叶查询子句和其他复合查询的组合,用于提取所需的信息。 Elasticsearch支持大量查询。 查询从查询关键字开始,然后以对象的形式在其中包含条件和过滤器。以下描

  • 本文向大家介绍使用Python查询SAP数据库,包括了使用Python查询SAP数据库的使用技巧和注意事项,需要的朋友参考一下 Python是最常用的面向对象编程语言之一,非常易于编码和理解。 为了将Python与SAP结合使用,我们需要安装Python SAP RFC模块,即PyRFC。它的可用方法之一是RFC_READ_TABLE,可以调用该方法以从SAP数据库中的表读取数据。 同样,PyRF