当其中一个字段有时出现时,在ElasticSearch中的两个字段上过滤

时间:2016-07-18 11:20:18

标签: elasticsearch

假设我们正在寻找最高价为100美元的鞋子。 鞋子有一个“价格”字段,但也可以有'discounted_price'字段。

举个例子:

{
    "_index": "shoes",
    "_type": "shoe",
    "_id": "1",
    "_score": 1,
    "_source": {
        "price": 150,
        "discounted_price": 90
    }
}
{
    "_index": "shoes",
    "_type": "shoe",
    "_id": "2",
    "_score": 2,
    "_source": {
        "price": 100,
        "discounted_price": null
    }
}

如何构建最高价格为100美元的查询,在这种情况下会返回两个文档?

1 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

POST /shoes/shoe/_search
{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [
        {
          "bool": {
            "filter": [
              {
                "range": {
                  "discounted_price": {
                    "lte": 100
                  }
                }
              },
              {
                "exists": {
                  "field": "discounted_price"
                }
              }
            ]
          }
        },
        {
          "bool": {
            "filter": [
              {
                "range": {
                  "price": {
                    "lte": 100
                  }
                }
              },
              {
                "missing": {
                  "field": "discounted_price"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

<强>更新

对于早于2.0的ES版本,您可以使用以下查询:

POST /shoes/shoe/_search
{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "minimum_should_match": 1,
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "range": {
                      "discounted_price": {
                        "lte": 100
                      }
                    }
                  },
                  {
                    "exists": {
                      "field": "discounted_price"
                    }
                  }
                ]
              }
            },
            {
              "bool": {
                "must": [
                  {
                    "range": {
                      "price": {
                        "lte": 100
                      }
                    }
                  },
                  {
                    "missing": {
                      "field": "discounted_price"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}