search_after 在弹性搜索中如何工作?
How does search_after work in elastic search?
我一直在尝试将 Elasticsearch 用于我们的应用程序,但限制为 10k 的分页实际上对我们来说是个问题,并且滚动 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
A field with one unique value per document should be used as the
tiebreaker of the sort specification. Otherwise the sort order for
documents that have the same sort values would be undefined and could
lead to missing or duplicate results. The _id field has a unique value
per document but it is not recommended to use it as a tiebreaker
directly. Beware that search_after looks for the first document which
fully or partially matches tiebreaker’s provided value. Therefore if a
document has a tiebreaker value of "654323" and you search_after for
"654" it would still match that document and return results found
after it. doc value are disabled on this field so sorting on it
requires to load a lot of data in memory. Instead it is advised to
duplicate (client side or with a set ingest processor) the content of
the _id field in another field that has doc value enabled and to use
this new field as the tiebreaker for the sort.
在您的情况下,如果您的 id
字段包含唯一值并且类型为 keyword
(或数字),那么您绝对没问题,可以使用它来使用 [=15= 进行分页].
所以第一个电话将是您在问题中遇到的电话:
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"sort": [
{"id": "asc"},
{"score": "desc"}
]
}
在您的响应中,您需要查看最后一次点击并从最后一次点击中获取 sort
值:
{
"_index" : "myindex",
"_type" : "_doc",
"_id" : "100000012",
"_score" : null,
"_source": { ... },
"sort" : [
"100000012", <--- take this
"98" <--- take this
]
}
然后在下一次搜索调用中,您将在 search_after
中指定该值
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"search_after": [ "100000012", "98" ], <--- add this
"sort": [
{"id": "asc"}
]
}
而下一个结果集的第一个命中将是id: 100000013
。而已。仅此而已。
如果您总是使用完整的 id
值进行排序,那么您所指的问题与您无关。它的工作方式是您始终使用先前结果中的最后一个 id
值。如果您要添加 "search_after": ["1000"]
那么您就会遇到他们提到的问题,但您没有理由这样做。
我一直在尝试将 Elasticsearch 用于我们的应用程序,但限制为 10k 的分页实际上对我们来说是个问题,并且滚动 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
A field with one unique value per document should be used as the tiebreaker of the sort specification. Otherwise the sort order for documents that have the same sort values would be undefined and could lead to missing or duplicate results. The _id field has a unique value per document but it is not recommended to use it as a tiebreaker directly. Beware that search_after looks for the first document which fully or partially matches tiebreaker’s provided value. Therefore if a document has a tiebreaker value of "654323" and you search_after for "654" it would still match that document and return results found after it. doc value are disabled on this field so sorting on it requires to load a lot of data in memory. Instead it is advised to duplicate (client side or with a set ingest processor) the content of the _id field in another field that has doc value enabled and to use this new field as the tiebreaker for the sort.
在您的情况下,如果您的 id
字段包含唯一值并且类型为 keyword
(或数字),那么您绝对没问题,可以使用它来使用 [=15= 进行分页].
所以第一个电话将是您在问题中遇到的电话:
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"sort": [
{"id": "asc"},
{"score": "desc"}
]
}
在您的响应中,您需要查看最后一次点击并从最后一次点击中获取 sort
值:
{
"_index" : "myindex",
"_type" : "_doc",
"_id" : "100000012",
"_score" : null,
"_source": { ... },
"sort" : [
"100000012", <--- take this
"98" <--- take this
]
}
然后在下一次搜索调用中,您将在 search_after
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"search_after": [ "100000012", "98" ], <--- add this
"sort": [
{"id": "asc"}
]
}
而下一个结果集的第一个命中将是id: 100000013
。而已。仅此而已。
如果您总是使用完整的 id
值进行排序,那么您所指的问题与您无关。它的工作方式是您始终使用先前结果中的最后一个 id
值。如果您要添加 "search_after": ["1000"]
那么您就会遇到他们提到的问题,但您没有理由这样做。