是否可以通过在Elasticsearch查询中搜索子文档来返回父数据?
我有两种文档类型,例如书和章,与父/子(非嵌套)相关。
我想对子文档运行搜索并返回子文档,其中包含父文档中的一些字段。我试图避免对父进行单独的查询。
更新
我能找到的唯一方法是使用has_child
查询,然后使用一系列聚合来钻回子项并再次应用查询/过滤器。然而,这似乎过于复杂和低效。
GET index/_search
{
"size": 10,
"query": {
"has_child": {
"type": "chapter",
"query": {
"term": {
"field": "value"
}
}
}
},
"aggs": {
"name1": {
"terms": {
"size": 50,
"field": "id"
},
"aggs": {
"name2": {
"top_hits": {
"size": 50
}
},
"name3": {
"children": {
"type": "type2"
},
"aggs": {
"docFilter": {
"filter": {
"query": {
"match": {
"_all": "value"
}
}
},
"aggs": {
"docs": {
"top_hits": {
"size": 50
}
}
}
}
}
}
}
}
}
}
答案 0 :(得分:2)
可以执行has_child
查询以返回带有top hits
聚合的父文档以返回子文档,但这有点麻烦。
将在1.5.0中发布的Inner Hits
功能可以满足您的需求。
http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.x/search-request-inner-hits.html
你可以从master构建源代码并试用它。
答案 1 :(得分:0)
正如Dan Tuffery在他的评论中所说,目前,这可以通过内部命中来实现,在Java中,您可以使用下一段代码更容易理解它。
SearchResponse searchResponse = this.transportClient.prepareSearch("your_index")
.setTypes("your_type")
.setQuery(QueryBuilders.filteredQuery(
null,
FilterBuilders.hasParentFilter(
"parent_type_name",
FilterBuilders.termFilter("foo", "foo"))
.innerHit(new QueryInnerHitBuilder()))
)
.execute().actionGet();
List<YourObject> list = new ArrayList<>();
for (SearchHit searchHit : searchHits.getHits()) {
YourObject yourObject = this.objectMapper.readValue(searchHit.getSourceAsString(), YourObject.class);
yourObject.setYourParentObject(this.objectMapper.readValue(searchHit.getInnerHits().get("parent_type_name").getAt(0).getSourceAsString(), YourParentObject.class));
list.add(yourObject);
}
答案 2 :(得分:0)
现在可以使用ElasticSearch完成此操作。只需在搜索查询中使用“ has_parent”即可:
'has_parent': {
'parent_type': 'book',
'query': {
'match_all': {}
},
'inner_hits': {}
}
结果将显示在响应的inner_hits中。