Elasticsearch - 匹配所有数组列表字段

Elasticsearch - Match all arraylist field

我几乎没有包含数组“items”的文档,我只想选择那些“items.name”等于“red”的文档。如果有任何文档是一种红色和另一种颜色,那么它不应该出现在结果中。

1.

{
  "items": [
    {
      "id": "4",
      "name": "red"
    },
    {
      "id": "5",
      "name": "blue"
    }
  ]
}
{
  "items": [
    {
      "id": "3",
      "name": "red"
    }
  ]
}
{
  "items": [
    {
      "id": "2",
      "name": "red"
    },
    {
      "id": "1",
      "name": "red"
    }
  ]
}

现在,我需要一个查询,其中只有文档 2 和 3 应该出现结果,因为所有“items.name”中都存在“red”。文档 1 被忽略,因为它也包含蓝色。

这是我使用脚本的第一个解决方案:

GET test/_search
{
  "runtime_mappings": {
    "all_red_items": {
      "type": "boolean",
      "script": {
        "source": "int count = 0; for (int i = 0; i < doc['items.name'].size(); i++) { if (doc['items.name'][i] != 'red') { count++ }} emit(count == 0);"
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "all_red_items": {
              "value": true
            }
          }
        }
      ]
    }
  }
}

这是我的正则表达式解决方案:

GET test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "items.name": {
              "value": "red"
            }
          }
        }
      ],
      "must_not": [
        {
          "regexp": {
            "items.name": "@&~(red)"
          }
        }
      ]
    }
  }
}

在发送请求之前,您需要准备以下索引:

DELETE test

PUT test
{
  "mappings": {
    "properties": {
      "items": {
        "properties": {
          "name": {
            "type": "keyword"
          }
        }
      }
    }
  }
}


POST test/_doc
{
  "items": [
    {
      "id": 6,
      "name": "red"
    },
    {
      "id": 5,
      "name": "blue"
    }
  ]
}

POST test/_doc
{
  "items": [
    {
      "id": 1,
      "name": "red"
    }
  ]
}


POST test/_doc
{
  "items": [
    {
      "id": 3,
      "name": "red"
    },
    {
      "id": 4,
      "name": "red"
    }
  ]
}

GET test/_mapping