elasticsearch查询结果排序

您所在的位置:网站首页 词频查询结果怎么是数字 elasticsearch查询结果排序

elasticsearch查询结果排序

2023-11-02 19:17| 来源: 网络整理| 查看: 265

相关性排序

默认情况下,结果集会按照相关性进行排序,相关性越高,排名越靠前。在Elasticsearch中相关性分值会用_score字段来给出一个浮点型的数值,所以默认情况下,结果集是以_score倒序排序的。 但是,有时候返回的_score是没有意义的,比如下面这个

{ "query": { "bool": { "filter": { "term": { "orgcode": "0120800214" } } } } }

过滤语句与_score没有关系,但是有隐含的查询条件match_all给所有的文档的_score设置了一个确定值,也就相当于每一个文档的相关性评分是相同的。

字段值排序

下面例子中,对结果集按照时间排序,这也是最常见的场景,将最新的文档靠前,我们使用sort参数排序。

{ "query": { "bool": { "filter": { "term": { "orgcode": "0120800214" } } } }, "sort": { "zcsj": { "order": "desc" } } }

你会发现这里有这两个不同点: 在这里插入图片描述

一、_score字段没有经过计算,因为它没有用作排序。二、zcsj字段被转为毫秒来当作排序依据了 首先,在每一个结果中增加了一个sort字段,它所包含的值是用来排序的。在这个例子当中zcsj字段在内部被转成了毫秒数,即长整型数字1487088000000等同于日期字符串 2017-02-14T16:00:00.000Z。 其次就是_score和max_score都是null,计算_score是非常消耗性能的,而且通常主要用作排序–我们不是用相关性用作排序的时候,就不需要计算其相关性,如果想强制计算其相关性,可以设置track_scores为true,如下所示。 { "query": { "bool": { "filter": { "term": { "orgcode": "0120800214" } } } }, "track_scores": "true", "sort": { "zcsj": { "order": "desc" } } } 默认排序

作为缩写,我们只需要指定排序的字段名称即可:

{ "query": { "bool": { "filter": { "term": { "orgcode": "0120800214" } } } }, "sort": "zcsj" }

字段值默认以升序排序,_score默认以降序排序。

多级排序

如果我们想合并一个查询语句,并且展示所有匹配的结果集使用第一排序是zcsj,第二排序是_score。

{ "query": { "bool": { "filter": { "term": { "orgcode": "0120800214" } } } }, "sort": { "zcsj": { "order": "desc" }, "_score": { "order": "desc" } } }

结果集会先用第一排序字段来排序,当用作第一字段排序的值相同时,然后再用第二排序字段来排序,以此类推。 但是_score不是多级排序必须的字段,我们可以使用几个不同的字段。

为多值字段排序

在为一个多值字段排序的时候,其实这些值本来没有固定的排序的,一个拥有多值的字段就是一个集合。 对于数字和日期而言,我们可以从多个值中取出一个来进行排序,我们可以使用min、max、avg、sum等模式,比如我们可以在likenum字段中选择最早的数字来进行排序。

{ "query": { "match_all": {} }, "sort": { "likenum": { "order": "desc", "mode": "min" }, "_score": { "order": "desc" } } }

在这里插入图片描述

多值字段字符串排序

analyzer字符串字段同时也是多值字段,在这些字段上排序往往得不到我们想要的值,比如分析一个字符"like a boy",它最终可能会得到三个值like、a、boy。例如我们想要按照第一个词首字母排序,如果第一个单词相同的话,在用第二个单词首字母排序,以此类推,可惜es在进行排序的时候 是得不到这些信息。 为了使一个String字段可以进行排序,它必须包含一个词:即完整的not_analyzer字符串,当然我们要对字段进行全文本搜索的时候还必须使用analyzer。 在_source下相同的字符串上排序两次会造成不必要的资源浪费。而我们想要的是一个字段中同时包含这两种索引方式,现在我们介绍一下在所有核心字段类型上通用的参数fields,这样我们就可以改变它的mapping

"name": { "type": "text", "fields":{ "raw": { "type":"keyword" } } }

改变后的多值字段mapping如下:

"name": { "type": "text", "fields": { "raw": { "type": "keyword" } } }

下面附上完整的代码(直接在linux服务器上执行)

curl -u elastic -H "Content-Type: application/json" -XPUT 'http://47.100.111.22:9200/bag/' -d ' { "settings": { "number_of_shards": 5, "number_of_replicas": 0 }, "mappings": { "book": { "properties": { "name": { "type": "text", "fields":{ "raw": { "type":"keyword" } } }, "author": { "index": "true", "type": "keyword" }, "price": { "index": "true", "type": "double" }, "date": { "format": "strict_date_optional_time||epoch_millis", "type": "date" } } } } }' name字段用于全文本的analyzed索引方式不变name.raw子字段索引方式是not_analyzer

现在改数据重建索引之后,我们可以用name来进行全文本搜索,也可以使用name.raw来进行排序,聚合。

{ "query": { "match": { "": "elasticsearch" } }, "sort": "name.raw" }

Tip:对analyzed字段进行强制排序的话会消耗大量的内存。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3