Elasticsearch – 按优先级例外进行过滤和按名称sorting

我试图按优先级例外进行过滤和名称sorting,这意味着即使结果按字母顺序sorting,我也希望首先出现一个特定的名称。

例如 – 这是我的基本查询

{ "from": 0, "size": 500, "min_score": 0.15, "query": { "filtered": { "filter": { "bool": { "must": [ { "exists": { "field": "brand.id" } } ] } } } }, "sort": [ { "brand.names.1.raw": "asc" } ] } 

简而言之,我希望这个数组[“百事可乐”,“可口可乐”,“可口可乐”]按照“可口可乐”的优先顺序进行sorting,从而将其sorting为“可口可乐” ,“可口可乐”,“百事可乐”]

现在它按字母顺序sorting。 我想到了一些可行的想法:

  1. 通过“匹配”增加一个“应该”。 但后来我有sorting“_score”的问题,它打破了我的字母sorting,虽然我首先按“_score”和品牌名称sorting。 添加到“bool”中的示例:“should”:[{“match”:{“brand.id”:{“query”:34709,“boost”:20}}}

  2. 我尝试了“聚合”,以便第一个查询(桶)将“匹配”具体的品牌名称和sortingalphabeticaly里面,第二个查询将按字母sorting只。 但我完全搞砸了。

我必须使用过滤 – >filter,我不能使用脚本查询。 谢谢。

更新这里是一个文件的例子,以及它如何sorting。 我希望“ccc”品牌优先,请帮我更新我的查询。

 { "_index": "retailer1", "_type": "product", "_id": "1", "_score": null, "_source": { "id": 1, "brand": { "names": { "1": "aaa" }, "id": 405 } }, "sort": [ "aaa" ] }, { "_index": "retailer1", "_type": "product", "_id": "2", "_score": null, "_source": { "id": 2, "brand": { "names": { "1": "bbb" }, "id": 406 } }, "sort": [ "bbb" ] }, { "_index": "retailer1", "_type": "product", "_id": "3", "_score": null, "_source": { "id": 3, "brand": { "names": { "1": "ccc" }, "id": 407 } }, "sort": [ "ccc" ] }, 

如果使用Elasticsearch版本1.x,以下查询应该为您提供预期的结果:(如果需要,可能需要适应一些原始字段)

 { "from": 0, "size": 500, "query": { "filtered": { "query": { "bool": { "should": [ { "term": { "brand.names.1": "ccc", "boost": 10 } }, { "exists": { "field": "brand.id" } } ] } }, "filter": { "exists": { "field": "brand.id" } } } }, "sort": [ "_score", { "brand.names.1": { "order": "asc" } } ] } 

在Elasticsearch 的更高版本上过滤后的查询被replace为bool查询 ,这个查询应该做这个工作(如果需要的话,可以使用与前一个类似的原始字段)

 { "from": 0, "size": 500, "query": { "bool": { "filter": { "exists": { "field": "brand.id" } }, "should": [ { "term": { "brand.names.1": "ccc" } } ] } }, "sort": [ "_score", { "brand.names.1": { "order": "asc" } } ] } 

在这两种情况下,如果您想让顶部填充多个首选匹配项,则可以使用boost函数按给定顺序

我在这里testing了localy。 同样为了简化查询,不要询问品牌IDS,因为品牌可能有很多名字。 如果你仍然想对名称进行sorting,那么你可以根据需要修改脚本

 POST stack/_search { "query": { "function_score": { "boost_mode": "replace", "query": { "bool": { "must": [ { "exists": { "field": "brand.id" } } ] } }, "script_score": { "script": { "params": { "ids": [ 406, 405 ] }, "inline": "return params.ids.indexOf(doc['brand.id'].value) > -1 ? 1000 - params.ids.indexOf(doc['brand.id'].value) : _score;" } } } } } 

如果品牌的优先级在索引时间已知,那么您可以直接在您的文档中将其索引为:

 "brand": { "name": "ccc", "priority":1000, "id": 407 } 

要显示在最上面的品牌可以具有较高的受欢迎程度值,而其他品牌可以将受欢迎程度值指定为较低的值。

通过这种索引方式,您可以直接使用brand.popularity作为主要sorting, brand.names作为次要sorting

 "sort" : [ { "brand.priority" : {"order" : "desc"}}, { "brand.name" : {"order" : "asc" }} ]