【问题标题】:Elasticsearch multiple range filters on same field同一字段上的 Elasticsearch 多个范围过滤器
【发布时间】:2015-09-11 02:35:07
【问题描述】:

我正在努力在我正在开发的网站中实现 elasticseach,并尝试构建一个多范围过滤器。有 2 个字段具有我需要过滤的范围:价格和评级。每个都应该能够一次选择多个范围。因此,例如,您应该能够按 80-85 OR 90-95 的评级进行过滤,同时还可以按 10-15 OR 20-25 的价格进行过滤。我正在使用post_filter 作为术语和范围过滤器,因为我正在为搜索结果构建分面导航。您可以在下面看到我发送的结构化 json。

{
  "from": 0,
  "size": 15,
  "query": {
    "multi_match": {
      "query": "taz 2003",
      "type": "most_fields",
      "operator": "or",
      "fields": [
        "name",
        "vintage",
        "brand^4",
        "review"
      ],
      "fuzziness": "1"
    }
  },
  "post_filter": {
    "bool": {
      "must": [
        {
          "term": {
            "vintage": "2009"
          }
        }
      ],
      "should": [
        {
          "range": {
            "price": {
              "gte": 10,
              "lt": 15
            }
          }
        },
        {
          "range": {
            "price": {
              "gte": 20,
              "lt": 25
            }
          }
        },
        {
          "range": {
            "rating": {
              "gte": 80,
              "lt": 85
            }
          }
        },
        {
          "range": {
            "rating": {
              "gte": 90,
              "lt": 95
            }
          }
        }
      ]
    }
  }
}

这几乎可行,但是因为所有范围都在 should bool 过滤器内,它使用 OR 组合它们,因此它只匹配其中一个过滤器。我需要的是它执行以下操作(在 SQL 中):

SELECT * FROM `table` where 
vintage = 2009 AND
(
    (
        price BETWEEN 10 AND 15 OR
        price BETWEEN 20 AND 25
    ) AND
    (
        rating BETWEEN 80 AND 85 OR
        rating BETWEEN 90 AND 85
    )
);

我目前不知道如何做到这一点。提前感谢您的帮助。

【问题讨论】:

  • 您是否尝试将所有过滤器放入"must"
  • 是的,但这不会返回任何结果,因为实体的评级不能在 80-85 和 90-95 之间,并且与价格相同
  • 哦,我明白了。应该可以嵌套布尔值。如果您要发布一些示例数据和所需的输出,我会看看我是否可以解决。

标签: elasticsearch


【解决方案1】:

一种方法是在must 中使用nested bool 查询

例子:

{
  "from": 0,
  "size": 15,
  "query": {
    "multi_match": {
      "query": "taz 2003",
      "type": "most_fields",
      "operator": "or",
      "fields": [
        "name",
        "vintage",
        "brand^4",
        "review"
      ],
      "fuzziness": "1"
    }
  },
  "post_filter": {
    "bool": {
      "must": [
        {
          "term": {
            "vintage": "2009"
          }
        },
        {
          "bool": {
            "should": [
              {
                "range": {
                  "price": {
                    "gte": 10,
                    "lt": 15
                  }
                }
              },
              {
                "range": {
                  "price": {
                    "gte": 20,
                    "lt": 25
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "should": [
              {
                "range": {
                  "rating": {
                    "gte": 80,
                    "lt": 85
                  }
                }
              },
              {
                "range": {
                  "rating": {
                    "gte": 90,
                    "lt": 95
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}

【讨论】:

  • 我试图使用 Nest 构建一个会生成这个的查询,但最后只是将一堆范围过滤器查询 ORing 到一个查询容器中,然后与我的过滤器的其余部分进行 ANDing查询(它们本身也是查询容器)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-03
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
相关资源
最近更新 更多