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))); }