首页 > 解决方案 > 在 Elasticsearch 中通过 id 获取上一个/下一个搜索结果的通用方法

问题描述

假设我的索引中有一百万(许多)个文档。我执行一个搜索查询,按某个键 X 对项目进行排序。

现在我有一个很长的结果列表:[..., id1, id2, id3, ...]

问题:我如何获取id1id3如果我知道id2但不想执行整个搜索/不想获取所有 ID?

我正在寻找适用于任何搜索查询的通用解决方案。给定一个肯定存在于查询结果中的 id,如何通过该 id 获取 prev/next。除了搜索其 prev/next 的 id 之外,查询不应具有任何其他知识。(换句话说,如果按标题排序并搜索 id X 的 prev/next,则在查询时不知道 X 的标题,只有 X 的 id。)

当然可以执行多个搜索查询并通过获取id2然后玩排序以获取 id 1 和 3 来获得相同的最终结果。

编辑:我认为 Luc E 的答案不是我想要的。在这种情况下,需要了解原始对象标题才能查询 prev/next。我正在寻找在查询时只知道 id 的解决方案。

示例数据如下所示:

[...
{id: 32, title: 'AAA'},
{id: 12, title: 'BBB'},
{id: 99, title: 'CCC'},
{id: 3, title: 'DDD'},
{id: 1001, title: 'EEE'},
...]

我知道的:id 99。我不知道的:id 99 的标题是什么。我想要的:按标题字段排序的上一个/下一个项目的 id(=3 和 12)。

换一种说法:我有 id 99,但我手中没有标题。我想要一个给我 id 3 和 12 的查询(它们是按标题排序的上一个/下一个)。

标签: elasticsearch

解决方案


你想做的就是所谓deep scrolling的,你只有两种方法可以做到:

  1. 滚动
  2. 搜索后

最简单的方法是search_after但您需要提出两个请求:

  • 一项要求id3
  • 另一个为id1

所以,在这个例子中,我正在寻找id2 : 128. 我可以使用该字段对文档进行排序,title并且我事先得到了titlefor id2which is的值title_of_128

要执行search_after,我必须_id在子排序条件上添加

这是我的查询:

POST test/_search
{
  "size": 2,
  "search_after": ["title_of_128","128"],
  "sort": [
    {
      "title": {
        "order": "asc"
      },
      "_id": {
        "order": "asc"
      }
    }
  ]
}

这个查询的结果id2id3

现在我反转排序的方向以检索id1

POST test/_search
{
  "size": 2,
  "search_after": ["title_of_128","128"],
  "sort": [
    {
      "title": {
        "order": "desc"
      },
      "_id": {
        "order": "desc"
      }
    }
  ]
}

这个查询的结果id2id1

请注意,不推荐使用 sort with,如果您想使用_id,最好的做法是在另一个字段中复制_idsearch_after


推荐阅读