在 Elasticsearch 中通过 id 获取上一个/下一个搜索结果的通用方法

pat*_*ate 5 elasticsearch

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

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

问:我如何才能id1id3,如果我知道id2,但不想执行整个搜索/不想让所有的IDS?

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

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

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

示例数据如下所示:

[...
{id: 32, title: 'AAA'},
{id: 12, title: 'BBB'},
{id: 99, title: 'CCC'},
{id: 3, title: 'DDD'},
{id: 1001, title: 'EEE'},
...]
Run Code Online (Sandbox Code Playgroud)

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

换句话说:我有 99 号 ID,但我手上没有标题。我想要一个给我 ids 3 和 12 的查询(它们是按标题排序的上一个/下一个)。

小智 4

你想做的事情叫做deep scrolling,你只有两种方法可以做到:

  1. 滚动
  2. 搜索后

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

  • 一项请求id3
  • 另一张是为了id1

所以,在这个例子中我正在寻找id2 : 128. 我可以使用该字段对文档进行排序,并且我已经预先获得了其中的title值。titleid2title_of_128

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

这是我的查询:

POST test/_search
{
  "size": 2,
  "search_after": ["title_of_128","128"],
  "sort": [
    {
      "title": {
        "order": "asc"
      },
      "_id": {
        "order": "asc"
      }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

该查询的结果id2id3

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

POST test/_search
{
  "size": 2,
  "search_after": ["title_of_128","128"],
  "sort": [
    {
      "title": {
        "order": "desc"
      },
      "_id": {
        "order": "desc"
      }
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

该查询的结果id2id1

请注意,不推荐使用 sort with,如果要使用,_id最佳实践是将 the 复制到另一个字段中_idsearch_after