【问题标题】:Hibernate Search : The field () used for the spatial query is not configured as spatial fieldHibernate Search : 用于空间查询的字段 () 未配置为空间字段
【发布时间】:2018-08-21 11:57:44
【问题描述】:

我有组织和坐标类。 坐标如下:

@Entity
@Table(name = "COORDINATES")
@Indexed
@Spatial
public class Coordinates implements Serializable {

private static final long serialVersionUID = 1L;

public Coordinates() {}

@Id
@Column(name = "id", nullable = false)
@SequenceGenerator(name = "generator", sequenceName = "COORDINATES_id_seq", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
private Long id;

@Field
@Latitude
@Column(name = "LATITUDE", nullable = false)
private Double latitude;

@Field
@Longitude
@Column(name = "LONGITUDE", nullable = false)
private Double longitude;

我将注解@IndexedEmbedded 放在Organization 的坐标字段中(即@Indexed + @Entity + @Table)。 为什么我的查询中无法识别空间特征?我有以下例外:

org.hibernate.search.exception.SearchException:HSEARCH000131: 用于空间的字段“organization.Organization#coordinates” 查询未配置为空间字段。检查正确使用 @Spatial 分别位于 SpatialFieldBridge org.hibernate.search.query.dsl.impl.ConnectedSpatialQueryBuilder.createSpatialQuery(ConnectedSpatialQueryBuilder.java:63) 在 org.hibernate.search.query.dsl.impl.ConnectedSpatialQueryBuilder.createQuery(ConnectedSpatialQueryBuilder.java:38)


编辑 1

我尝试向 Spatial 注释添加名称,但收到错误消息,提示找不到 @Latitude 和 @Longitude。 所以我尝试实现Hibernate的坐标,将@Entity更改为@Embeddable,在Organization类中将@IndexedEmbedded更改为@Spatial coordinates 属性,在我的 Coordinates 类中删除 @Latitude + @Longitude,覆盖 getLatitude()getLongitude()。现在我有以下异常:

org.hibernate.AnnotationException: @OneToOne 或 @ManyToOne on com.(...).model.organization.Organization.coordinates 引用一个未知实体: com.(...).model.localization.Coordinates

我正在使用:

  • 休眠核心:5.2.12.Final
  • hibernate-jpamodelgen:5.2.12.Final
  • hibernate-search-orm : 5.8.2.Final
  • hibernate-search-elasticsearch:5.8.2.Final

我与其他开发人员交谈过,他们似乎需要在较新版本中更改的功能,因此我们暂时不想更改。

这是组织类中有趣的部分:

@Entity
@Table(name = "ORGANIZATION", uniqueConstraints = {@UniqueConstraint(columnNames = { "CODE" }) })
@Indexed
public class Organization implements Serializable, FileEntity {
    // lots of attributes, getters, setters, constructor
    @Spatial(name = "location", spatialMode = SpatialMode.RANGE)
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "COORDINATES_ID")
    private Coordinates coordinates;
}

以及修改后的坐标类:

@Embeddable
@Table(name = "COORDINATES")
@Indexed
public class Coordinates implements org.hibernate.search.spatial.Coordinates, Serializable {
    // serial, constructor, id get+set
    @Field
    @Column(name = "LATITUDE", nullable = false)
    private Double latitude;

    @Field
    @Column(name = "LONGITUDE", nullable = false)
    private Double longitude;
    @Override
    public Double getLatitude() {
        return this.latitude;
    }

    @Override
    public Double getLongitude() {
        return this.longitude;
    }
}

编辑 2

我在@Latitude 和@Longitude 中添加了“(of = "location")”。 我仍然有错误:

错误信息: {"root_cause":[{"type":"query_shard_exception","re​​ason":"失败 查找 geo_point 字段 [coordinates.location]" (...)

也许它来自查询? 查询:

final BooleanJunction bool = queryBuilder.bool().must(queryBuilder.bool()                                                              
    .should(...)
    .should(...)
    .should(queryBuilder
        .spatial()
        .onField("coordinates.location")
        .within(12, Unit.KM)
        .ofLatitude(form.getLatitude())
        .andLongitude(form.getLongitude())
        .createQuery())
    .createQuery())
    .must(...)
    .must(...)
    .must(...);
final FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(bool.createQuery(), Organization.class);
fullTextQuery.setMaxResults(form.getMaximumNumberOfResult());
fullTextQuery.setProjection(FullTextQuery.SPATIAL_DISTANCE, FullTextQuery.THIS);
fullTextQuery.setSpatialParameters(form.getLatitude(), form.getLongitude(), "coordinates.location");
fullTextQuery.setProjection(FullTextQuery.THIS, FullTextQuery.SCORE);

Organization 中的“coordinates”字段是@IndexedEmbedded,Coordinates 类是你写的。

【问题讨论】:

    标签: hibernate-search hibernate-spatial


    【解决方案1】:

    所以,首先,Hibernate Search 一开始就成功启动有点奇怪,因为您的映射包含一个错误:您应该在@Spatial 注释上设置name 属性。然后 Hibernate Search 将在 Coordinates 类型中创建一个具有该名称的字段(比如说“位置”)。 完成后,您将能够使用 coordinates.location 名称从 Organization 类型中查询该字段。

    我知道,在这种情况下听起来有点傻,但通常你放置@Spatial 注释的实体是业务类型,而不是表示坐标的东西,所以更有意义。

    另一种选择是将您的Coordinates 类型转换为可嵌入而不是实体,使其实现org.hibernate.search.spatial.Coordinates,并将@Spatial 注释放在Organization#coordinates 属性上,而不是将其放在@987654333 上@ 类型。那么您将不再需要@IndexedEmbedded@Latitude/@Longitude,实际上您可以在查询时只使用coordinates 字段名称。

    如果以上不行,请添加你正在使用的Hibernate Search和Hibernate ORM的版本,以及Organization类的代码。


    编辑:回应您的编辑...

    关于找不到@Latitude/@Longitude注解:您需要使用这些注解的of属性来匹配您的字段名称。

    如果您切换到@Embeddable,这将导致如下情况:

    @Entity
    @Table(name = "COORDINATES")
    @Indexed
    @Spatial(name = "location")
    public class Coordinates implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    public Coordinates() {}
    
    @Id
    @Column(name = "id", nullable = false)
    @SequenceGenerator(name = "generator", sequenceName = "COORDINATES_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
    private Long id;
    
    @Field
    @Latitude(of = "location")
    @Column(name = "LATITUDE", nullable = false)
    private Double latitude;
    
    @Field
    @Longitude(of = "location")
    @Column(name = "LONGITUDE", nullable = false)
    private Double longitude;
    
    }
    

    关于切换到嵌入式后的“org.hibernate.AnnotationException”:您需要删除coordinates 属性上的@ManyToOne 并将其替换为@Embedded。嵌入属性与关联有很大不同,请看Hibernate ORM documentation

    【讨论】:

    • 感谢您的提示。我编辑了我的问题来回答你的问题,因为它似乎没有解决。
    • @Marie 我为您在编辑中提到的问题添加了解决方案。
    • 再次编辑。我不知道为什么它不起作用。顺便说一句,谢谢你帮助我。
    • @Marie 我看到您正在使用 Elasticsearch 集成。每当您更改 Hibernate Search 映射时,您都应该重新生成 Elasticsearch 架构,否则 Elasticsearch 将无法正常工作。请参阅"schema management strategies" in the documentation 在开发过程中,我会推荐drop-and-create,尤其是如果您可以轻松地在启动时重新索引所有数据。
    • 是的,我们使用的是drop-and-create
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多