ElasticSearch按名称查找并返回最便宜的

时间:2015-03-19 11:47:16

标签: sorting elasticsearch match

我已经签订合同'键入以下映射:

{
  "contract" : {
    "properties" : {
      "active" : {
        "type" : "boolean"
      },
      [ ... ] 
      "device" : {
        "properties" : {
          [ ... ] 
          "title" : {
            "type" : "string"
          },
          [ ... ] 
        }
      },
      "handset_price" : {
        "type" : "double"
      },
      "id" : {
        "type" : "string",
        "index" : "not_analyzed"
      },
      [ ... ] 
      "monthly_price" : {
        "type" : "double"
      },
      [ ... ] 
    }
  }
}

现在我需要为给定的设备获得最便宜的交易(合约)。这就是我现在所拥有的:

{
        "query": {
            "match": {
                "device.title": device_name
            }
        },
        "size": 1,
        "sort":
            [
                {"monthly_price": {"order": "asc"}},
                {"handset_price": {"order": "asc"}}
        ]
    }

device_name是字符串(例如Lumia 530)。

当我搜索三星'时,我得到最便宜的三星Galaxy s3 Mini。问题是寻找三星Note'再次给了我Galaxy s3,而不是返回现有的三星音符交易之一。

关于我做错了什么的任何线索?

3 个答案:

答案 0 :(得分:1)

您的问题是您按价格对结果进行排序,但这并未将结果的相关性考虑在内。

在搜索“三星”时,按升序排序,您将始终拥有最便宜的“三星Galaxy s3 Mini”作为第一个结果。

如果您想先使用Samsung Note设备,则必须按分数排序(默认排序)。

如果您想按分数排序,然后为每个分数值选择最便宜的结果作为第一个结果,请在排序中添加“_score”,如下所示:

{
        "query": {
            "match": {
                "device.title": device_name
            }
        },
        "size": 1,
        "sort":
            [
                {"_score": {"order": "desc"}},
                {"monthly_price": {"order": "asc"}},
                {"handset_price": {"order": "asc"}}
        ]
    }

建议不要使用min_score,除非对于某些高级案例,如documentation中所述。分数是相对值,设置绝对阈值可能会导致奇怪的结果。

答案 1 :(得分:1)

问题是由OR查询中使用默认match operator引起的,如果Samsung Note找到最便宜的Samsung或{{ 1}}。切换到Note运算符只会返回包含ANDSamsung的合同:

Note

答案 2 :(得分:-1)

min_score删除分数低的文档。

{
        "query": {
            "match" : {
                "device.title" : {
                    "query" : device_name
                }
            }
        },
        "min_score": 1,
        "track_scores": True,
        "size": 1,
        "sort":
            [
                {"monthly_price": {"order": "asc"}},
                {"handset_price": {"order": "asc"}}
        ]
    }