我想搜索一组嵌套文档,只返回符合特定条件的文档。
示例映射将是:
{"book":
{"properties":
{
"title":{"type":"string"},
"chapters":{
"type":"nested",
"properties":{"title":{"type":"string"},
"length":{"type":"long"}}
}
}
}
}
}
所以,说我想寻找标题为“结语”的章节。 并非所有的书籍都有这样的章节,但是如果我使用嵌套查询,那么我会得到一本 这样一章的书中的所有章节。虽然我感兴趣的是章节本身就有这样的标题。
我主要关注i / o和网络流量,因为可能会有很多章节。
另外,有没有办法只检索嵌套文档,而不包含doc?
答案 0 :(得分:4)
这是我偶然发现的一个非常古老的问题,所以我将展示两种不同的方法来解决这个问题。
让我们先准备索引和一些测试数据:
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
中 聚合器然后返回嵌套的命中。嵌套的点击是在 感知隐藏的迷你文档,它们是常规文档的一部分 已配置嵌套字段类型的映射。top_hits
聚合器具有在包装时取消隐藏这些文档的能力 在nested
或reverse_nested
聚合器中。阅读有关嵌套的更多信息 嵌套类型映射。
response from Elasticsearch是(IMO)更漂亮(它似乎更快地返回它(虽然这不是一个科学观察))和"更容易"解析。