这是我偶然发现的一个非常古老的问题,所以我将展示两种不同的方法来解决这个问题。
让我们先准备指数和一些测试数据:
PUT /bookindex
{
"mappings": {
"book": {
"properties": {
"title": {
"type": "string"
},
"chapters": {
"type": "nested",
"properties": {
"title": {
"type": "string"
},
"length": {
"type": "long"
}
}
}
}
}
}
}
PUT /bookindex/book/1
{
"title": "My first book ever",
"chapters": [
{
"title": "epilogue",
"length": 1230
},
{
"title": "intro",
"length": 200
}
]
}
PUT /bookindex/book/2
{
"title": "Book of life",
"chapters": [
{
"title": "epilogue",
"length": 17
},
{
"title": "toc",
"length": 42
}
]
}
现在,我们已经在Elasticsearch这些数据,我们可以检索只是使用inner_hits
相关命中。这种方法非常简单,但我更喜欢最后概述的方法。
# Inner hits query
POST /bookindex/book/_search
{
"_source": false,
"query": {
"nested": {
"path": "chapters",
"query": {
"match": {
"chapters.title": "epilogue"
}
},
"inner_hits": {}
}
}
}
的inner_hits
嵌套查询返回的文档,其中每个命中包含与所有的匹配的文档,其中包括计分信息的一个inner_hits
对象。你可以看到response。
我对此类查询的首选方法是使用nested aggregation和filtered子聚合,其中包含top_hits
子聚合。查询看起来像:
# Nested and filter aggregation
POST /bookindex/book/_search
{
"size": 0,
"aggs": {
"nested": {
"nested": {
"path": "chapters"
},
"aggs": {
"filter": {
"filter": {
"match": { "chapters.title": "epilogue" }
},
"aggs": {
"t": {
"top_hits": {
"size": 100
}
}
}
}
}
}
}
}
的top_hits
子聚集是一个中 别人做实际的检索嵌套文档的 和支持from
和size
性能。从文档:
如果top_hits
聚合包装在nested
或reverse_nested
聚合,然后被返回嵌套命中。嵌套命中是 意义隐藏迷你文档是常规文档的一部分,其中 已配置嵌套字段类型的映射。如果聚合器在nested
或reverse_nested
聚合器中被包装为 ,那么聚合器能够取消隐藏这些文档。详细了解嵌套在 中的嵌套类型映射。
response from Elasticsearch是(IMO)更漂亮(它似乎更快地返回(虽然这不是科学观察))并且“更容易”解析。
不是章节总是嵌套在书籍对象下? – concept47
您不能使用嵌套文档afaik。然而,你可以将它改造成父母(书) - 儿童(章)关系。在这种情况下,您的问题+答案类似于http://stackoverflow.com/questions/7431889/how-can-i-retrieve-matching-children-only –
github上的相关问题,以便能够返回匹配的嵌套 - 上下文︰https://github.com/elasticsearch/elasticsearch/issues/1383和较新的https://github.com/elasticsearch/elasticsearch/issues/3022 –