Elasticsearch:获取 nested 类型数组中的所有元素

Posted Elastic 中国社区官方博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch:获取 nested 类型数组中的所有元素相关的知识,希望对你有一定的参考价值。

在我之前的文章 “Elasticsearch: object 及 nested 数据类型” 对 nested 数据类型做了一个比较详细的介绍。在实际使用中,你在构建查询时肯定会遇到一些问题。根据官方文档介绍,nested 类型字段在隐藏数组中索引其每个项目,这允许独立于索引文档搜索这些项目。今天我带来一个问题:问如何获得一个文档,其整个 item 列表必须与一个子句匹配。 让我举个例子让你更清楚。

我有一个 item 字段设置为 nested 的索引。 我索引了两个文档,其中一个所有项目的 status 都为 active,另一个则不全是。

PUT nested_index

  "mappings": 
    "properties": 
      "description": 
        "type": "text"
      ,
      "item": 
        "type": "nested",
        "properties": 
          "value": 
            "type": "text"
          ,
          "status": 
            "type": "keyword"
          
        
      
    
  
POST nested_index/_doc

  "description": "nested A",
  "item": [
    
      "value": "a",
      "status": "active"
    ,
    
      "value": "ab",
      "status": "active"
    
  ]


POST nested_index/_doc

  "description": "nested B",
  "item": [
    
      "value": "b",
      "status": "inactive"
    ,
    
      "value": "bc",
      "status": "active"
    
  ]

如上所示,第一个文档里的 status 都是 active 的状态,而第二个文档的其中一个 status 状态是 active,另外一个是 inactive 状态。

现在我们想要查询的问题是:搜索到 status 都是 active 的文档。

也许你会想到使用如下的查询:

GET nested_index/_search

  "query": 
    "nested": 
      "path": "item",
      "query": 
        "term": 
          "item.status": 
            "value": "active"
          
        
      
    
  

上面命令查询的结果是:


  "took": 1,
  "timed_out": false,
  "_shards": 
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  ,
  "hits": 
    "total": 
      "value": 2,
      "relation": "eq"
    ,
    "max_score": 0.35667494,
    "hits": [
      
        "_index": "nested_index",
        "_id": "xRoaRIYB2XodIZsbUfzi",
        "_score": 0.35667494,
        "_source": 
          "description": "nested A",
          "item": [
            
              "value": "a",
              "status": "active"
            ,
            
              "value": "ab",
              "status": "active"
            
          ]
        
      ,
      
        "_index": "nested_index",
        "_id": "xhoaRIYB2XodIZsbWvzm",
        "_score": 0.35667494,
        "_source": 
          "description": "nested B",
          "item": [
            
              "value": "b",
              "status": "inactive"
            ,
            
              "value": "bc",
              "status": "active"
            
          ]
        
      
    ]
  

显然两个文档都被查询到了。这个不是我们想要的结果。

解决它的方法是使用两个 must_not 子句。 最里面的 must_not 子句将过滤文档 A,因为所有项目都具有 active 状态。 最外层的 must_not 将反转操作,迄今为止省略的文档 A 将可用,而文档 B 将不可用且不会出现在响应中。

GET nested_index/_search

  "query": 
    "bool": 
      "must_not": [
        
          "nested": 
            "path": "item",
            "query": 
              "bool": 
                "must_not": [
                  
                    "term": 
                      "item.status": 
                        "value": "active"
                      
                    
                  
                ]
              
            
          
        
      ]
    
  

上面的命令结果为:


  "took": 2,
  "timed_out": false,
  "_shards": 
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  ,
  "hits": 
    "total": 
      "value": 1,
      "relation": "eq"
    ,
    "max_score": 0,
    "hits": [
      
        "_index": "nested_index",
        "_id": "xRoaRIYB2XodIZsbUfzi",
        "_score": 0,
        "_source": 
          "description": "nested A",
          "item": [
            
              "value": "a",
              "status": "active"
            ,
            
              "value": "ab",
              "status": "active"
            
          ]
        
      
    ]
  

这次显然只有 nested A 文档被搜索到。

以上是关于Elasticsearch:获取 nested 类型数组中的所有元素的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch:获取 nested 类型数组中的所有元素

从 NEST C# 嵌套聚合中获取 Elasticsearch 结果

如何从 elasticsearch.net / NEST 获取 geo_point 字段的距离

ElasticSearch+NetCore 第二篇Nest封装

为啥 ElasticSearch Nest Query 中会出现转义反斜杠?

如何使用 Elasticsearch 的 NEST“.net 客户端”对所有记录进行分页?