【问题标题】:Returning a partial nested document in ElasticSearch在 ElasticSearch 中返回部分嵌套文档
【发布时间】:2013-05-28 09:30:40
【问题描述】:

我想搜索一组嵌套文档并仅返回符合特定条件的文档。

一个示例映射是:

{"book":
    {"properties":
        {
         "title":{"type":"string"},
         "chapters":{
                     "type":"nested",
                     "properties":{"title":{"type":"string"},
                                   "length":{"type":"long"}}
                                  }
                     }
          }
     }
}

所以,假设我想查找标题为“尾声”的章节。 不是所有的书都有这样的章节,但是如果我使用嵌套查询,我会得到一本书中这样的章节的所有章节。虽然我感兴趣的是有这样一个标题的章节本身。

我主要关心 i/o 和网络流量,因为可能有很多章节。

另外,有没有办法只检索嵌套文档而不包含包含文档?

【问题讨论】:

标签: elasticsearch


【解决方案1】:

这是我偶然发现的一个非常古老的问题,因此我将展示两种不同的处理方法。

让我们先准备索引和一些测试数据:

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 aggregationfiltered 子聚合,其中包含 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 子聚合是进行实际检索的聚合 嵌套文档并支持fromsize 属性 其他。来自文档:

如果 top_hits 聚合器包含在 nestedreverse_nested 中 聚合器然后返回嵌套命中。嵌套命中位于 感知作为常规文档一部分的隐藏迷你文档 已配置嵌套字段类型的映射。 top_hits 如果已包装,聚合器可以取消隐藏这些文档 在 nestedreverse_nested 聚合器中。阅读更多关于嵌套 嵌套类型映射。

response from Elasticsearch (IMO) 更漂亮(而且它似乎返回得更快(尽管这不是科学观察))并且“更容易”解析。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多