我对elasticsearch和spring数据elasticsearch非常陌生,在查询嵌套对象时遇到了一些问题。
我使用ElasticSearch存储库在ElasticSearch中保存一个嵌套模型实例。因此,elasticsearch中只有一个条目包含所有数据,据我所知,这意味着我有一个嵌套文档。
我需要使用Criteria实现一个相对复杂的查询来迭代构建查询。当我尝试使用点表示法访问嵌套属性时,如
startPoint.providingTimeRange.startTime
我没有得到任何搜索结果(但匹配的数据存在于elasticsearch中)。
在使用嵌套字段和映射的Spring Data Elastic Search中,我发现spring-data-elasticsearch能够使用nestedQuery查询嵌套对象。
有没有办法将标准搜索与嵌套查询结合起来?
先谢谢你克里斯托夫
更新1:为了提供一些示例代码,我创建了一个演示项目,其中包含类似于真实项目中的嵌套对象:https://github.com/empulse-gmbh/elasticsearchtest
该示例将查找在特定时间的特定地点的食品卡车。
在本例中,我使用了一个存储库来持久化嵌套的实体。
我使用了两种(都不起作用)方法来查询嵌套对象:
/*
* add search criteria by timerange. it is assumed in timerange from
* is always before to.
*/
TimeRange searchTimeRange = foodTruckSearch.getSearchTimeRange();
if (searchTimeRange != null) {
String startTimePath = "locationPoint.timeRange.from";
String endTimePath = "locationPoint.timeRange.to";
searchCriteria = searchCriteria.and(
new Criteria(startTimePath).between(searchTimeRange
.getFrom().getTime(), searchTimeRange.getTo()
.getTime())).or(
new Criteria(endTimePath).between(searchTimeRange
.getFrom().getTime(), searchTimeRange.getTo()
.getTime()));
}
以及:
TimeRange searchTimeRange = foodTruckSearch.getSearchTimeRange();
if (searchTimeRange != null) {
String startTimePath = "locationPoint.timeRange.from";
String endTimePath = "locationPoint.timeRange.to";
searchQuery.must(nestedQuery(
"locationPoint",
boolQuery().should(
rangeQuery(startTimePath).from(
searchTimeRange.getFrom().getTime()).to(
searchTimeRange.getTo().getTime())).should(
rangeQuery(endTimePath).from(
searchTimeRange.getFrom()).to(
searchTimeRange.getTo()))));
}
更新2:多亏了Mohsin Husen,我能够使用嵌套搜索。按时间范围搜索现在可以工作了。除了Mohsin的建议之外,我还必须改变创建和启动本地Elasticsearch实例的方式:
elasticSearchNode = NodeBuilder.nodeBuilder().clusterName("foodtruck-test").local(true).build();
如果不提供blosterName,则不会创建嵌套文档。
我的下一个(希望是最后一个)问题是使用geo_distance搜索过滤器。如果我在Elasticsearch中做对了,我会使用查询来进行模糊搜索,如“喜欢”或“范围”,并使用是/否或距离过滤器。
所以我尝试将QueryBuilder和FilterBuilder与spring-data-elasticsearch一起使用,但失败了。
根据文档中的示例,我重构了模型,以便Location类使用spring数据elasticsearch对象GeoPoint。
我使用以下内容进行搜索:
/*
* add search criteria for radius search
*/
FilterBuilder searchFilter = null;
if (foodTruckSearch.getLatitude() != null
&& foodTruckSearch.getLongitude() != null) {
if (foodTruckSearch.getSearchRadiusInKilometers() == null) {
foodTruckSearch.setSearchRadiusInKilometers(5);
}
searchFilter = geoDistanceFilter("location.point")
.distance(
foodTruckSearch.getSearchRadiusInKilometers()
+ "km").lat(foodTruckSearch.getLatitude())
.lon(foodTruckSearch.getLongitude());
}
if (searchFilter != null) {
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(
searchQuery, searchFilter);
return IteratorUtils.toList(foodTruckRepository.search(
nativeSearchQuery).iterator());
} else {
return IteratorUtils.toList(foodTruckRepository.search(searchQuery)
.iterator());
}
我得到的例外是:
org.elasticsearch.action.search.SearchPhaseExecutionException: Failedtoexecutephase[query_fetch],
allshardsfailed;shardFailures{
[1][searchexample][0]: SearchParseException[[searchexample][0]: query[MatchNoDocsQuery],
from[0],
size[10]: ParseFailure[Failedtoparsesource[{
"from": 0,
"size": 10,
"query": {
"bool": {
}
},
"post_filter": {
"geo_distance": {
"location.point": [6.9599115,
50.9406645],
"distance": "10km"
}
}
}]]];nested: QueryParsingException[[searchexample]failedtofindgeo_pointfield[location.point]] ;
}
是否有任何示例可用如何使用geo_distance(嵌套?)过滤器与Spring数据弹性搜索?
该异常是由于在中提供了默认映射器而导致的
return new ElasticsearchTemplate(elasticSearchNode.client());
删除这个错误的映射器导致spring数据elasticsearch将正确的映射放入elasticsearch。
如果要为geo\u distance search启用实体,请使用
@GeoPointField
注释以标记包含纬度/经度值的字段。
此外,FoodTruckServiceImpl被更改为使用过滤器,而不是查询。
GitHub中的项目已更新,是一个功能完整的示例。可以使用FoodTruck示例了解spring数据elasticsearch的第一步。
在没有详细阅读的情况下,我发现了您代码中的一些问题,如下所示
1) 当您使用多级嵌套文档时,您必须使用快照版本(您正在使用),因为spring数据elasticsearch M1发行版存在已修复的错误。(https://jira.springsource.org/browse/DATAES-53)
2)您在实体中声明嵌套类型错误,必须如下所示
@Field(type=FieldType.Nested)
private LocationPoint locationPoint;
@Field(type = FieldType.Nested)
private TimeRange timeRange;
3) 条件查询不会处理嵌套对象,它是为处理简单实体而构建的,因为它使用query\u string查询数据。因此,使用elasticsearchTemplate或repository来查询嵌套对象。
4)您必须为嵌套对象指定完整路径
e、 g,搜索定位点时。时间范围。起点和位置点。时间范围。您必须按以下方式使用
String startTimePath = "locationPoint.timeRange.from";
String endTimePath = "locationPoint.timeRange.to";
searchQuery.must(nestedQuery(
"locationPoint.timeRange",
boolQuery().should(
rangeQuery(startTimePath).from(
searchTimeRange.getFrom().getTime()).to(
searchTimeRange.getTo().getTime())).should(
rangeQuery(endTimePath).from(
searchTimeRange.getFrom()).to(
searchTimeRange.getTo()))));
希望这能解决你的问题。
我试图在spring数据中编写一个findBy,希望所有员工的第一部门状态都处于活动状态。是否可以使用spring数据方法名称,而不使用自定义查询? 类似于List findByDepartmentFirstStatusIsActive(); 我试了几次,但都没用,所以我想没有!!!
对我如何做这件事有什么建议吗? 更新:我将如下所示的方法添加到存储库中: 但是在代码中调用此方法时,我会得到以下错误。不确定我使用的Redis/Spring库是否有问题。我在用 null 当我执行findAll,findById时,它会返回结果。当我执行findByPersonalInfo_UserId()并传递像:Anthony.Turner或Ashleigh.Hayes这样的值时,什么也不会显
我有一个班级结构 我使用数据绑定,房间和匕首。我得到编译错误为找不到类数据库组件,可能是因为房间不允许持久化的嵌套对象。为了启用,我使用了@嵌入式注释,但仍然得到相同的错误。但是如果我使用@Ignore注释,指示不处理该字段的Room;编译正在成功进行。 请参阅https://developer.android.com/topic/libraries/architecture/room.html#
问题内容: 我在使用hibernate标准时遇到问题。我正在尝试制定一个条件,在其中查看查询返回的类的成员对象的ID。 例如: 结果是一个例外: 该班确实包含讲座变量,又包含了admin变量。我尝试过使用,效果很好。 这样的对象层次结构可以限制的级别数是否有限制? 谢谢! 代码段: “用户”类扩展了该类,该类又扩展了一个类,该类具有以下方法: 从Hibernate映射XML: 这是表: 问题答案:
我想从API中获取countynames,它返回嵌套对象; 等等,有200多个国家,每个县都有自己的“编号”。最后,我想列出所有“姓名”信息。我想我应该使用JsonDeserializer,但不幸的是我不能。
我从foursquare收到了一个json形式的响应。我尝试访问对象的某些部分,但没有成功。如何访问对象的地址?这是我试过的代码。 以下是json响应的一个示例: 完整的回应可以在这里找到