首页 > 解决方案 > 按 ElasticSearch 中嵌套数组中的值排序并交错结果

问题描述

我有一个索引,其中每个文档都有一个嵌套字段,其中包含 0 个或多个嵌套文档。我需要能够对这些嵌套文档的值进行排序,但我希望我的结果在嵌套文档的级别进行排序。例如,如果我有这两个文件:

{"_id":1,"name":"dogs","menu":[{"item_name":"hot dog","price":5}]},
{"_id":2,"name":"bar","menu":[{"item_name":"beer","price":10},{"item_name":"soda","price":2}]}

我按 menu.price desc 排序,我需要得到这样的结果:

{"_id":2,"name":"bar","menu":[{"item_name":"beer","price":10}]},
{"_id":1,"name":"dogs","menu":[{"item_name":"hot dog","price":5}]},
{"_id":2,"name":"bar","menu":[{"item_name":"soda","price":2}]}

但如果我只是按 menu.price desc 排序,我会得到:

{"_id":2,"name":"bar","menu":[{"item_name":"beer","price":10},{"item_name":"soda","price":2}]},
{"_id":1,"name":"dogs","menu":[{"item_name":"hot dog","price":5}]}

有没有办法在 Elastic 中实现这种预期行为?我有一个需要正确分页的大型数据集,因此在查询时间之后我无能为力。在顶层具有嵌套字段的新索引对我来说不是一个可扩展的解决方案,因为随着时间的推移会添加许多嵌套字段。

我目前正在使用 ElasticSearch 7.12.1

标签: elasticsearch

解决方案


基于示例,我假设您要返回顶级文档;但想在嵌套级别排序。这在弹性搜索中得到支持;请参考这部分文档

但是,如果您想“解包”并将嵌套文档与非嵌套文档一起排序,则不受支持(正如评论之一所建议的那样)。我建议先阅读上述文档,看看它是否符合您的需求(看起来可能)

关于嵌套文档和可伸缩性的注意事项。如果索引很大 - 嵌套文档将消耗更多资源并影响性能。

一些因素...

1 - 每个嵌套文档在内部被索引为单独的文档,并使用(块连接查询)在查询时加入;这样就增加了文件的数量

2 - 如果您有许多包含数万个嵌套实体的文档,索引时间堆使用率可能会很高

3 - 嵌套文档使用堆来缓存一些数据结构,因此您最终可能会使用更多堆。

因此,如果有办法避免嵌套 - 绝对要这样做!- 但在某些情况下它们是有意义的!


推荐阅读