Geolocation 使用QueryDSL查询数据库中的近距离点

Geolocation 使用QueryDSL查询数据库中的近距离点,geolocation,querydsl,Geolocation,Querydsl,我的应用程序中有以下实体: 成员 家庭广告 地址 在成员实体中: @OneToOne(cascade=CascadeType.ALL) private Address address; ... @OneToMany(fetch = FetchType.LAZY, mappedBy = "member") private List<Advertisement> advertisements; @NotNull @ManyToOne(fetch = FetchType.LA

我的应用程序中有以下实体:

  • 成员
  • 家庭广告
  • 地址
成员
实体中:

@OneToOne(cascade=CascadeType.ALL)
    private Address address;
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "member")
private List<Advertisement> advertisements;
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
private Member member;
@Entity
public class Address {

    private String formattedAddress;
    private double latitude;
    private double longitude;
}
完整的
地址
实体:

@OneToOne(cascade=CascadeType.ALL)
    private Address address;
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "member")
private List<Advertisement> advertisements;
@NotNull
@ManyToOne(fetch = FetchType.LAZY)
private Member member;
@Entity
public class Address {

    private String formattedAddress;
    private double latitude;
    private double longitude;
}
我正在尝试查找其成员地址在所需地址20公里以内的所有家庭广告实例。

以下是我的想法:

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);
我现在得到以下异常:

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);
我试过这样的方法:

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

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

                ).list(qFamilyAdvertisement);
List foundfamilyAdvertisions=from(QfamilyAdvertisient)。其中(QfamilyAdvertisient.member.address.in(
新建JPASubQuery().from(QAddress.address).where(formula.lt(20)))
).列表(Qfamily广告);
上面给出了公式,但我不确定如何在QueryDSL中表示非相关子查询,尤其是上面的in运算符似乎有问题

edit4

下面的子查询现在可以工作了:

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

此路径太长,无法立即初始化

qFamilyAdvertisement.member.address.latitude;

请在此阅读Querydsl中有关路径初始化的更多信息。我已经修改了我的实体,现在得到一个:
IllegalArgumentException:只有根路径才允许加入:familyAdvertisiment.member.address
。我已经编辑了我的帖子。from参数必须是根路径,一个变量。我正在尝试使用子查询,但中的
方法不会像sql中那样接受子查询。你知道怎么做吗,蒂莫?我试过你的方法,甚至用同样的gps创建了地址。然而,结果什么也没有归还。