search_after 如何在弹性搜索中工作?

时间:2021-06-25 08:31:40

标签: elasticsearch elastic-stack

我一直在尝试将 Elasticsearch 用于我们的应用程序,但限制为 10k 的分页对我们来说实际上是一个问题,并且由于必须超时问题,scroll API 也不是推荐的选择。

我发现 Elasticsearch 有一个叫做 search_after 的东西,它是支持深度分页的理想解决方案。我一直试图从文档中理解它,但它有点令人困惑,并且无法清楚地理解它是如何工作的。

假设我的文档中有三列,id, first_name, last_name,这里 ID 是唯一的主键。

{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "sort": [
        {"id": "asc"}      
    ]
}

我可以使用上述查询来使用 search_after 功能吗?我在他们的文档中读到,我们必须在排序中使用多个唯一值,而不仅仅是一个 (ID),但是正如您在我的数据集中知道的那样,我只有 ID 作为唯一值。 如何将 search_after 用于我的数据集示例?

我无法理解所陈述的问题,如果我使用一个独特的决胜局进行排序?有人可以帮助用外行术语解释这一点吗?

https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-request-search-after.html

<块引用>

每个文档具有一个唯一值的字段应用作 排序规范的决胜局。否则排序顺序为 具有相同排序值的文档将是未定义的,并且可能 导致结果丢失或重复。 _id 字段具有唯一值 每个文件,但不建议将其用作决胜局 直接地。请注意 search_after 查找第一个文档 完全或部分匹配 tiebreaker 提供的值。因此如果一个 文档的 tiebreaker 值为“654323”,您 search_after 查找 “654”它仍然会匹配该文档并返回找到的结果 之后。此字段上的 doc 值被禁用,因此对其进行排序 需要在内存中加载大量数据。相反,建议 复制(客户端或使用设置的摄取处理器)的内容 另一个字段中的 _id 字段已启用并使用 doc 值 这个新字段作为排序的决胜局。

1 个答案:

答案 0 :(得分:1)

在您的情况下,如果您的 id 字段包含唯一值并且类型为 keyword(或数字),那么您绝对没问题,并且可以使用它来使用 search_after 进行分页。

所以第一个电话将是您的问题:

{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "sort": [
        {"id": "asc"}      
    ]
}

在您的响应中,您需要查看最后一次点击并从最后一次点击中获取 sort 值:

{
    "_index" : "myindex",
    "_type" : "_doc",
    "_id" : "100000012",
    "_score" : null,
    "_source": { ... },
    "sort" : [
      "100000012"                                <--- take this
    ]
}

然后在您的下一次搜索调用中,您将在 search_after

中指定该值
{
    "size": 10,
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "search_after": [ "100000012" ],             <--- add this
    "sort": [
        {"id": "asc"}      
    ]
}

下一个结果集的第一个命中将是 id: 100000013。而已。没什么可说的了。

如果您总是使用完整的 id 值进行排序,您所指出的问题与您无关。它的工作方式是始终使用先前结果中的最后一个 id 值。如果您要添加 "search_after": ["1000"],那么您就会遇到他们提到的问题,但您没有理由这样做。

相关问题