2017-03-07 839 views
8

我想按名称筛选并按名称排序优先级异常,这意味着即使结果按字母顺序排序,我也希望首先显示特定名称。Elasticsearch - 根据名称进行过滤和按优先级排序

例如 - 这是我的基本查询

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

总之,我想这个数组[“百事可乐”,“RC-可乐”,“可口可乐”]来通过给顶部进行排序优先到“rc-cola”,以便将其排序为[“rc-cola”,“coca-cola”,“pepsi”]

现在它按字母顺序排序。 我想到了可以工作的一些想法:

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

  2. 我试过“聚合”,以便第一个查询(存储桶)将 “匹配”特定品牌名称并按字母顺序排序,第二个查询将仅按字母顺序排序。但我完全搞砸了。

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

UPDATE 下面是一个文档示例以及它如何排序。 我希望首先将“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" 
    ] 
}, 
+0

正在关注。我也试图在没有脚本的情况下做同样的事情。 – Yissachar

+0

这是什么阵列?你想要品牌按照你的优先顺序排序还是什么? –

+0

如果您发布文档示例和预期结果,它将有助于理解 –

回答

4

如果排序。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 The filtered query is replaced by the bool query, 此查询应该做的工作的更高版本(带类似的适应是如果需要上一个使用原始字段)

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

在这两种情况下,你可以使用升压功能,如果你想拥有一个充满多于一个的首选比赛前,在给定的订单

+0

谢谢,看起来像它的作品 –

3

我已经测试了localy在这里。同样为了简化查询,不要询问名字,而要询问品牌IDS,因为品牌可能有很多名称。如果您仍然希望在名称排序做,那么你可以修改脚本,你想

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;" 
     } 
     } 
    } 
    } 
} 
+1

谢谢,但正如我所说:“我必须使用过滤 - >过滤器,我不能使用脚本查询。” –

3

如果品牌的优先级在索引时间是已知的,那么你就可以直接索引它在你的文档,如:

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

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

通过这种方式建立索引,你可以直接使用brand.popularity作为主排序和brand.names为使用Elasticsearch版本1次要排序

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

谢谢,但我不想依赖索引 –

+0

您是否意味着任何品牌都可以针对不同的查询具有不同的优先级? – Rahul

+1

不,我知道我可以在索引中做到这一点,我不想让它取决于索引..我有几个丛林的原因。我正在寻找其他选项。谢谢 –

相关问题