如何让多个范围查询在elasticsearch中工作?

时间:2017-07-12 14:38:34

标签: django elasticsearch django-haystack

我正在尝试在range中使用多个elasticsearch 2.4.5查询,但在相互组合时似乎不起作用。

我正在建立一个必须能够搜索和过滤产品的在线商店,而我正在使用elasticsearch来添加这些功能。商店必须能够按以下字段过滤产品:pricenum_in_stockpopularity

以下是elasticsearch内部存储每个字段的方式:

  • popularity = float(即0.0098736465783,将转换为百分比以表示该产品的受欢迎程度)

  • price = float(即5.890000000,将四舍五入并转换为正确的价格格式)

  • num_in_stock = long(即10)

这就是我所知道的:

  1. 当我单独使用任何字段执行单个范围查询时(pricepopularitynum_in_stock),它可以正常工作。例如,当我按受欢迎程度过滤时 - 让我们说0.05 (5%) - 0.75 (75%) - 它运作正常。

  2. 但是,当我合并多个range查询时,popularity范围查询无效。但是,pricenum_in_stock范围确实有效。在下面的示例查询中,范围pricenum_in_stock工作正常,但范围popularity不起作用!

  3. 以下是一个示例查询:

    {
      "query": {
        "query": {
          "constant_score": {
            "filter": {
              "bool": {
                "must": [
                  {
                    "bool": {
                      "must": {
                        "range": {
                          "popularity": {
                            "gte": 0,
                            "lte": 0.02
                          },
                          "price": {
                            "gte": 0,
                            "lte": 10.25
                          },
                          "num_in_stock": {
                            "gte": 0,
                            "lte": 15
                          }
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      },
      "from": 0,
      "size": 1
    }
    

    以下是响应

    的内容
    {
      "took": 10,
      "timed_out": false,
      "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
      },
      "hits": {
        "total": 9,
        "max_score": null,
        "hits": [
          {
            "_index": "store",
            "_type": "modelresult",
            "_id": "product.360",
            "_score": null,
            "_source": {
              "product_name": "Tide Laundry Detergent",
              "price": 5.15,
              "popularity" : 0.044386262065587822,
              "num_in_stock": 5
            }
          }
        ]
      }
    }
    

    正如您所看到的,我希望popularity0过滤到0.02,但它会给我一个popularity大于此值的结果!

    这对我来说是个大问题,因为商店必须能够同时按多个范围进行过滤。有哪些策略可以解决这个问题?

1 个答案:

答案 0 :(得分:1)

范围查询的正确构造类似于

"bool" : {
  "must" : [
    {
      "range" : {
        "popularity" : ...
      }
    },
    {
      "range" : {
        "price" : ...
      }
    },
    {
      "range" : {
        "num_in_stock" : ...
      }
    },
  ]
}