我想搜索一组嵌套文档,然后仅返回那些符合特定条件的文档。
映射示例为:
{"book":
{"properties":
{
"title":{"type":"string"},
"chapters":{
"type":"nested",
"properties":{"title":{"type":"string"},
"length":{"type":"long"}}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以,说我想寻找标题为“结尾”的章节。并不是所有的书有这样的章节,但如果我使用嵌套查询我会得到,因此,在一本书,所有章节都有这样的一章。虽然我只感兴趣的标题是章节本身。
我主要关注I / O和网络流量,因为可能会有很多章节。
另外,有没有一种方法可以只检索嵌套文档,而无需包含文档?
我偶然发现了一个很老的问题,因此我将展示两种不同的处理方式。
让我们先准备索引和一些测试数据:
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
}
]
}
Run Code Online (Sandbox Code Playgroud)
现在我们已经在Elasticsearch中获得了这些数据,我们可以使用来仅检索相关的匹配inner_hits。这种方法非常简单,但是我更喜欢最后概述的方法。
# Inner hits query
POST /bookindex/book/_search
{
"_source": false,
"query": {
"nested": {
"path": "chapters",
"query": {
"match": {
"chapters.title": "epilogue"
}
},
"inner_hits": {}
}
}
}
Run Code Online (Sandbox Code Playgroud)
该inner_hits嵌套查询返回的文件,其中每个命中包含inner_hits所有匹配的文件,包括计分信息的对象。您可以看到响应。
对于此类查询,我的首选方法是使用嵌套聚合和包含子聚合的已过滤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
}
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
该top_hits子聚集是一个做嵌套的文件和支持的实际检索from和size等特性。从文档中:
如果
top_hits聚合器包装在nested或reverse_nested聚合器中,则将返回嵌套的匹配。从某种意义上说,嵌套命中是隐藏的迷你文档,它们是常规文档的一部分,在映射中已配置了嵌套字段类型。如果top_hits聚合器包装在聚合器nested或reverse_nested聚合器中,则它可以取消隐藏这些文档。在嵌套类型映射中阅读有关嵌套的更多信息。
Elasticsearch(IMO)的响应更漂亮(并且似乎返回得更快(尽管这不是科学观察))并且解析起来“更容易”。
| 归档时间: |
|
| 查看次数: |
2989 次 |
| 最近记录: |