Elasticsearch 是否支持 AND 查询多个值?

Does Elasticsearch support AND query for multiple values?

ElasticSearch 版本:5.3

我在弹性搜索中存储了一个项目数组。

userId: "123"
items: [
  {
    "range": {
      "from": 10,
      "to": 30
    },
    "id": "1"
  },
  {
    "range": {
      "from": 20,
      "to": 100
    },
    "id": "2"
  },
  {
    "range": {
      "from": 5,
      "to": 90
    },
    "id": "3"
  },
]

这只是一条记录。将其视为包含项目键的多条记录。 现在我想用 id 执行搜索查询,它是受尊重的范围。所以我当前的查询是这样的

GET product/item/_search{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "items.id": "1"
          }
        },
        {
          "range": {
            "items.range.from": {
              "gte": 20,
              "lte": 30
            }
          }
        },
        {
          "range": {
            "items.range.to": {
              "gte": 20,
              "lte": 30
            }
          }
        },

      ]
    }
  }
}

目前,这将执行一个搜索查询,其 id=1 且范围值从 >= 20 到 <= 30。因此它将 return 所有包含 id=2 且具有范围的记录在 20 到 30 之间。因此,即使在其他记录中,如果 id=1 不存在,它也会搜索范围值,如果范围匹配,将 return 记录。

相反,我想搜索 id=1 且 id 的值应在 20 到 30 之间的记录。 所以我的问题是弹性搜索是否支持这种中间和查询?

您需要 items 字段在映射中为 nested,如下所示:

PUT product
{
  "mappings": {
    "item": {
      "properties": {
        "itemId": {
          "type": "long"
        },
        "items": {
          "type": "nested",
          "properties": {
            "id": {
              "type": "long"
            },
            "range": {
              "properties": {
                "from": {
                  "type": "long"
                },
                "to": {
                  "type": "long"
                }
              }
            }
          }
        }
      }
    }
  }
}

那么你就可以这样查询了:

GET product/item/_search
{
  "query": {
    "nested": {
      "path": "items",
      "query": {
        "bool": {
          "filter": [
            {
              "term": {
                "items.id": "1"
              }
            },
            {
              "range": {
                "items.range.from": {
                  "gte": 20,
                  "lte": 30
                }
              }
            },
            {
              "range": {
                "items.range.to": {
                  "gte": 20,
                  "lte": 30
                }
              }
            }
          ]
        }
      }
    }
  }
}

PS:我建议您查看 integer_range data type 而不是 range.from/to 对象。只是我的两分钱