Elasticsearch排序(三)
Elasticsearch中排序是通过设置score字段来进行排序,score是一个浮点类型,所以我们对靠前的数据设置一个较大的值,然后根据倒序排列。
同样对于航班号查询,有时候需要根据航班号,日期查询出所有的航班号,用户会输入185,2018-12-01,这时需要返回所有相关航司的航班号。
比如匹配的航班有:CA1858,B6185,QF185,ZH1858,对于精确匹配,B6185、QF185要排在CA1858、ZH1858之前,对于非精确排序,CA航司要排在ZH航司前面
创建一个索引
之前我们对航班号创建了一个索引,用户可以输入CA1,出现CA1*的结果,现在用户输入185,是纯数字型的,所以我们需要单独一个字段(flightNum)保存这个航班数字,然后对它创建索引
PUT flight
{
"settings": {
"analysis": {
"analyzer": {
"flightNoAndNumAnalyzer": {
"tokenizer": "flightNoAndNumTokenizer"
}
},
"tokenizer": {
"flightNoAndNumTokenizer": {
"type": "edge_ngram",
"min_gram": 3,
"max_gram": 8,
"token_chars": ["letter","digit"]
}
}
}
},
"mappings": {
"dynamic": {
"properties": {
"flightNo": {
"type": "text",
"analyzer" : "flightNoAndNumAnalyzer"
},
"flightNum": {
"type": "text",
"analyzer" : "flightNoAndNumAnalyzer"
}
}
}
}
}
如果是航班数字查询,我们只需要根据航司来设定优先级,同时设定航班数字全匹配的优先级最高,然后查询的时候再通过constant_score统一来设置boost参数
GET flight/dynamic/_search
{
"query": {
"bool": {
"must": [
{"prefix": {
"flightNum": {
"value": "185"
}
}}
],
"should": [
{
"constant_score": {
"filter": {
"term": {
"airline": "CA"
}
},
"boost": 4
}
},
{
"constant_score": {
"filter": {
"term": {
"airline": "ZH"
}
},
"boost": 3
}
},
{
"constant_score": {
"filter": {
"term": {
"airline": "B6"
}
},
"boost": 2
}
},
{
"constant_score": {
"filter": {
"term": {
"airline": "QF"
}
},
"boost": 1
}
},
{
"constant_score": {
"filter": {
"term": {
"flightNum": "185"
}
},
"boost": 10
}
}
]
}
}
}
可以看到CA航司比B6高,但是当查询flightNum为185的时候,评分设置为最高,所以B6186会优先显示,其次是QF185,最后是CA1858和ZH1858 具体代码实现:
//航班数字优先级设置
BoolQueryBuilder qb = QueryBuilders.boolQuery()
.must(prefixQuery("flightNum", keyword))
.should(constantScoreQuery(matchQuery("flightNum", keyword)).boost(10f))
//航司优先级设置
airNumer.put("CA", 4f);
airNumer.put("ZH", 3f);
airNumer.put("B6", 4f);
airNumer.put("QF", 1f);
for (String airline : airNumer.keySet()) {
queryBuilder.should(constantScoreQuery(matchQuery("airline", airline)).boost(airNumer.get(airline)));
}