按多个字段对ElasticSearch查询进行排序

时间:2020-07-01 15:52:13

标签: elasticsearch

我有一些数据要按照特定的顺序进行排序。

我在此处查看了关于SO的几个问题,Elasticsearch sort on multiple queries很有帮助。据我所知,我以正确的顺序取回了数据,但它并不总是相同的数据,而且对于查询返回的内容似乎非常随机。

我的问题是,如何使我的数据正确排序并每次获得期望的数据?

示例数据

[
    {
        id: 00,
        ...
        current_outage: {
            device_id: 00,
            ....
        },
        forecasted_outages: [
            {
                device_id: 00
            }
        ]
    },
    {
        id: 01,
        ...
        current_outage: {
            device_id: 01,
            ....
        },
        forecasted_outages: []
    },
    {
        id: 02,
        ...
        current_outage: null,
        forecasted_outages: [
            {
                device_id: 02
            }
        ]
    },
    {
        id: 03,
        ...
        current_outage: null,
        forecasted_outages: []
    },
]

当前查询

bool: {
    should: [
        {
            constant_score: {
                boost: 6,
                filter: {
                    nested: {
                        path: 'current_outage',
                        query: {
                            exists: {
                                field: 'current_outage'
                            }
                        }
                    }
                }
            }
        },
        {
            nested: {
                path: 'forecasted_outages',
                query: {
                    exists: {
                        field: 'forecasted_outages'
                    }
                }
            }
        }
    ]
}

仅重申一下,以上查询以我期望的格式/排序方法返回数据,但每次都不会返回我期望的数据。据我所知,返回的数据非常随机。

排序标准

  • 首先:同时包含current_outage和一个或多个forecasted_outages的数据
  • 第二:仅包含current_outage的数据
  • 第三:仅包含forecasted_outages
  • 的数据

编辑

根据用户的不同,返回的数据可以是零到数千个结果。用户可以选择对数据进行分页或返回其所有相关数据。

编辑2

返回的数据将是从零到1,000的匹配。

1 个答案:

答案 0 :(得分:0)

如果搜索结果大于10(默认结果大小),并且所有文档都具有相同的分数(在您的情况下,可能是因为您获得的是恒定分数),那么每次运行返回的数据可能会有所不同(具有随机性)感觉。)

这样做的原因是,搜索结果会从不同的分片合并,直到命中数达到10,其余结果都将被忽略。因此,根据合并的碎片,每次运行都可以得到不同的结果。

增大结果大小以包括所有搜索结果可以为每次运行提供相同的数据。

更新

将分片计数更改为1可能会有所帮助(如果已经创建了索引,则可以关闭并重新打开索引)。

PUT /twitter/_settings
{
    "index" : {
        "number_of_shards" : 1
    }
}