【问题标题】:Failed to find geo_point field using @Spatial from hibernate search无法使用休眠搜索中的@Spatial 找到 geo_point 字段
【发布时间】:2018-09-21 11:10:53
【问题描述】:

我需要实施一种解决方案,旨在使用位置过滤我的一个搜索查询。您将在这里找到我的实体以及我如何使用@Spatial 注释:

@Entity
@Indexed
@Spatial(spatialMode = SpatialMode.RANGE)
@Table(name = "ORGANIZATION", uniqueConstraints = { @UniqueConstraint(columnNames = { "CODE" }) })
public class Organization implements Serializable, FileEntity {

    ...

    @Latitude
    @Column(name = "LATITUDE")
    private Double latitude;

    @Longitude
    @Column(name = "LONGITUDE")
    private Double longitude;

   ...

}

索引没有发现任何错误,这是我使用 elasticsearch 查询找到的结果:

GET http://localhost:9201/com.supralog.lexis.model.organization.organization
{
    "com.supralog.lexis.model.organization.organization" : {
        "aliases" : { },
        "mappings" : {
        "com.supralog.lexis.model.organization.Organization" : {
            "properties" : {
                "_hibernate_default_coordinates" : {
                    "properties" : {
                        "lat" : {
                            "type" : "float"
                        },
                        "lon" : {
                            "type" : "float"
                        }
                    }
                },
                ...
            }
        }
    }
}

GET http://localhost:9201/com.supralog.lexis.model.organization.organization/_search?from=0&size=1
{
    "took" : 1,
    "timed_out" : false,
    "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
    },
    "hits" : {
       "total" : 15628,
       "max_score" : 1.0,
       "hits" : [
           {
               "_index" : "com.supralog.lexis.model.organization.organization",
               "_type" : "com.supralog.lexis.model.organization.Organization",
               "_id" : "...",
               "_score" : 1.0,
               "_source" : {
                   ...
                   "_hibernate_default_coordinates" : {
                       "lat" : 49.1886203,
                       "lon" : -0.38740259999997306
                   },
                   ...
               }
           }
       ]
   }
}

在检查索引看起来没问题后,我尝试查询给定半径 100 公里内的所有组织对象:

    final Coordinates coordinates = Point.fromDegrees(form.getLatitude(), form.getLongitude());
    final String search = StringUtils.join(terms, " ");

    final FullTextSession fullTextSession = Search.getFullTextSession(sessionFactory.getCurrentSession());
    final QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder()
            .forEntity(Organization.class).get();

    final org.apache.lucene.search.Query elasticQuery = queryBuilder.spatial().within(100,Unit.KM).ofCoordinates(coordinates).createQuery();

    final FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(elasticQuery, Organization.class);
    fullTextQuery.setMaxResults(form.getMaximumNumberOfResult());
    fullTextQuery.setProjection(FullTextQuery.THIS, FullTextQuery.SCORE);

我的问题就在这里,当我尝试执行这个查询时,我有以下返回语句:

Request: POST /com.supralog.lexis.model.organization.organization/_search with parameters {from=0, size=50}
Response: 400 'Bad Request' with body 
{
    "error": {
        "root_cause": [
            {
                "type": "query_shard_exception",
                "reason": "failed to find geo_point field [_hibernate_default_coordinates]",
                "index_uuid": "phOfJTOyRvetHyZrfeUmrA",
                "index": "com.supralog.lexis.model.organization.organization"
            }
        ],
        "type": "search_phase_execution_exception",
        "reason": "all shards failed",
        "phase": "query",
        "grouped": true,
        "failed_shards": [
            {
                "shard": 0,
                "index": "com.supralog.lexis.model.organization.organization",
                "node": "9DCzSp6kS5KGtMq6tzywzg",
                "reason": {
                    "type": "query_shard_exception",
                    "reason": "failed to find geo_point field [_hibernate_default_coordinates]",
                    "index_uuid": "phOfJTOyRvetHyZrfeUmrA",
                    "index": "com.supralog.lexis.model.organization.organization"
                }
            }
        ]
    },
    "status": 400
}

为了修复它,我尝试为@Spatial 记录设置一个名称,我尝试让我的实体实现坐标等。但是我总是得到相同的结果。看起来hibernate-search没有将我的位置索引为geo_point,原因是它在查询时失败了......

您对我在文档中遗漏的内容有任何想法吗?

使用的版本 :: hibernate : 5.3 ;休眠搜索:5.10;弹性搜索:5.6

【问题讨论】:

    标签: elasticsearch hibernate-search hibernate-spatial


    【解决方案1】:

    Elasticsearch 映射错误:

        "com.supralog.lexis.model.organization.Organization" : {
            "properties" : {
                "_hibernate_default_coordinates" : {
                    "properties" : {
                        "lat" : {
                            "type" : "float"
                        },
                        "lon" : {
                            "type" : "float"
                        }
                    }
                },
                ...
            }
        }
    

    “_hibernate_default_coordinates”下有一个“properties”属性意味着“_hibernate_default_coordinates”是“object”类型,而它应该是“geo_point”类型。

    最可能的解释是您没有在建立索引之前生成架构,而 Elasticsearch 试图根据它收到的文档动态地自动生成它。如您所见,这是一个非常糟糕的主意,因为 Elasticsearch 猜测架构错误的风险非常高。

    你应该看看documentation about configuration。特别是,你应该选择一个合适的index schema management strategy

    简而言之,将以下内容放入hibernate.properties

    在开发环境中:Hibernate Search会尽力而为,但可能会失败,并且数据不会被神奇地重新索引,你必须自己做

    hibernate.search.default.elasticsearch.index_schema_management_strategy update
    

    在生产环境中:您必须自己仔细更新架构,并在更新应用程序时计划mass reindexing

    hibernate.search.default.elasticsearch.index_schema_management_strategy create
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 2019-06-21
      • 1970-01-01
      • 2015-02-01
      • 2020-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多