ES排序

排序

为了按照相关性来排序,需要将相关性表示为一个数值。在 Elasticsearch 中, 相关性得分 由一个浮点数进行表示,并在搜索结果中通过 _score 参数返回, 默认排序是 _score 降序。

有时,相关性评分对你来说并没有意义。例如,下面的查询返回所有 user_id 字段包含 1 的结果:

GET /_search
{
    "query" : {
        "bool" : {
            "filter" : {
                "term" : {
                    "user_id" : 1
                }
            }
        }
    }
}

这里没有一个有意义的分数:因为我们使用的是 filter (过滤),这表明我们只希望获取匹配 user_id: 1 的文档,并没有试图确定这些文档的相关性。 实际上文档将按照随机顺序返回,并且每个文档都会评为零分

如果评分为零对你造成了困扰,你可以使用 constant_score 查询进行替代:

GET /_search
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "term" : {
                    "user_id" : 1
                }
            }
        }
    }
}

这将让所有文档应用一个恒定分数(默认为 1 )。它将执行与前述查询相同的查询,并且所有的文档将像之前一样随机返回,这些文档只是有了一个分数而不是零分。

按照字段的值排序

在这个案例中,通过时间来 进行排序是有意义的,最新的排在最前。 我们可以使用 sort 参数进行实现:

GET /_search
{
    "query" : {
        "bool" : {
            "filter" : { "term" : { "user_id" : 1 }}
        }
    },
    "sort": { "date": { "order": "desc" }}
}

你会注意到结果中的两个不同点:

"hits" : {
    "total" :           6,
    "max_score" :       null, 
    "hits" : [ {
        "_index" :      "us",
        "_type" :       "tweet",
        "_id" :         "14",
        "_score" :      null, 
        "_source" :     {
             "date":    "2014-09-24",
             ...
        },
        "sort" :        [ 1411516800000 ] 
    },
    ...
}
  • _score 不被计算, 因为它并没有用于排序。
  • date 字段的值表示为自 epoch (January 1, 1970 00:00:00 UTC)以来的毫秒数,通过 sort 字段的值进行返回。

首先我们在每个结果中有一个新的名为 sort 的元素,它包含了我们用于排序的值。 在这个案例中,我们按照 date 进行排序,在内部被索引为 自 epoch 以来的毫秒数 。 long 类型数 1411516800000 等价于日期字符串 2014-09-24 00:00:00 UTC 。

其次 _scoremax_score 字段都是 null 。计算 _score 的花销巨大,通常仅用于排序; 我们并不根据相关性排序,所以记录 _score 是没有意义的。如果无论如何你都要计算 _score , 你可以将 track_scores 参数设置为 true 。

多级排序

假定我们想要结合使用 date_score 进行查询,并且匹配的结果首先按照日期排序,然后按照相关性排序:

GET /_search
{
    "query" : {
        "bool" : {
            "must":   { "match": { "tweet": "manage text search" }},
            "filter" : { "term" : { "user_id" : 2 }}
        }
    },
    "sort": [
        { "date":   { "order": "desc" }},
        { "_score": { "order": "desc" }}
    ]
}

排序条件的顺序是很重要的。结果首先按第一个条件排序,仅当结果集的第一个 sort 值完全相同时才会按照第二个条件进行排序,以此类推。

多级排序并不一定包含 _score 。你可以根据一些不同的字段进行排序,如地理距离或是脚本计算的特定值。

多值字段的排序

一种情形是字段有多个值的排序, 需要记住这些值并没有固有的顺序;一个多值的字段仅仅是多个值的包装,这时应该选择哪个进行排序呢?

对于数字或日期,你可以将多值字段减为单值,这可以通过使用 minmaxavg 或是 sum 排序模式 。 例如你可以按照每个 date 字段中的最早日期进行排序,通过以下方法:

"sort": {
    "dates": {
        "order": "asc",
        "mode":  "min"
    }
}
在Elasticsearch中,排序问题可能出现在聚合操作中。根据引用的描述,Elasticsearch在排序操作时,会先对每个分片进行排序,然后将每个分片的前17名结果进行再次聚合和排序,最终返回排序后的前5条记录作为结果。这个排序策略来源于官方给出的算式,根据算式,如果请求只发往一个分片,就返回前5条记录;如果请求发送给多个分片,每个分片返回的记录数是5 * 1.5 = 17。这个策略可能导致在返回的数据中,实际的排序结果与期望的排序结果不一致。 因此,如果你在Elasticsearch中遇到排序问题,可以检查是否涉及到了多个分片,并且了解Elasticsearch的排序策略。你可以参考引用提供的链接来了解更多关于Elasticsearch排序操作的详细信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Elasticsearch聚合学习之五:排序结果不准的问题分析](https://blog.csdn.net/boling_cavalry/article/details/90319399)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [3. elasticsearch 汇总排序问题剖析](https://blog.csdn.net/wangzhiqiang123456/article/details/123073114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值