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

2023年2月20日   |   by mebius

tgcode

在我之前的文章 “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"
tgcode            },
            {
              "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.sttgcodeatus": {
                        "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:轻松处理 CSV 数据

我们知道 CSV 是一种非常流行的数据格式。在 Elastic Stack 中,我们有很多的方式来摄入 CSV 格式的数据。我们可以先看看一个常用的数据摄入数据流: 如上所示,我们可以采取不同的方法来对数据进行摄入。我们可以在不同的地方对数据进行处理。如上所示…

Tags: