【问题标题】:Elasticsearch number of results changes with paginationElasticsearch 的结果数量随分页而变化
【发布时间】:2020-08-19 12:16:01
【问题描述】:

我正在使用 Elasticsearch 7.6.0 并对我的一个查询进行了分页。它似乎运作良好,我可以使用搜索 fromsize 参数来改变每页和所选页面的结果数。

    query = 'sample query'
    items_per_page = 12
    page = 0

    es_query = {'query': {
        'bool': {
            'must': [{
                'multi_match': {
                    'query': query,
                    "fuzziness": "AUTO",
                    "operator": "and",
                    'fields': ['title^2', 'description']
                },
            }]
        }
    }, 'min_score': 5.0}

    res = es.search(index='my-index', body=es_query, size=items_per_page, from_=items_per_page*page)
    hits = sorted(res['hits']['hits'], key=lambda x: x['_score'], reverse=True)

    print(res['hits']['total']['value']) # This changes depending on the page provided

我注意到返回的结果数量取决于提供的页面,这对我来说毫无意义!结果的数量也在波动,这进一步让我感到困惑:第 0 页,233 项。第 1 页,157 项。第 2 页,157 项。第 3 页,233 项...

为什么res['hits']['total']['value'] 依赖于大小和来自参数?

【问题讨论】:

  • 你设置了items_per_page = 12,第0页返回了233项?

标签: elasticsearch pagination


【解决方案1】:

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-track-total-hits

通常,如果不访问所有匹配项,就无法准确计算总命中数,这对于匹配大量文档的查询来说代价高昂。 track_total_hits 参数允许您控制应如何跟踪点击总数。鉴于通常具有命中数的下限就足够了,例如“至少有 10000 个命中”,因此默认设置为 10,000。这意味着请求将准确计算总命中数,最高可达 10,000 次命中。如果您在某个阈值之后不需要准确的命中数,那么加快搜索速度是一个很好的权衡。

当设置为 true 时,搜索响应将始终跟踪准确匹配查询的命中数(例如,当 track_total_hits 设置为 true 时,total.relation 将始终等于“eq”)。否则,搜索响应中“total”对象中返回的“total.relation”决定了如何解释“total.value”。 “gte”值表示“total.value”是与查询匹配的总命中数的下限,“eq”值表示“total.value”是准确计数。

【讨论】:

  • 我很欣赏这个建议,但不幸的是这并没有解决问题。我仍然看到 res['hits']['total']['value'] 的变化
【解决方案2】:

len(res['hits']['hits']) 将始终返回与items_per_page 中指定的数字相同的数字(即在您的情况下为 12),但最后一页除外,它可能返回小于或等于 12 的数字。

但是,res['hits']['total']['value']索引中的文档总数,而不是返回的结果数。如果文档数量增加,则意味着新文档在最后一个查询和当前查询之间被索引。

【讨论】:

    【解决方案3】:

    搜索是分布式的,并被发送到所有持有与搜索索引匹配的分片的节点。然后将所有结果合并并返回。有时,并非所有分片都可以搜索。当

    • 集群很忙
    • 由于恢复过程,特定分片不可用
    • 搜索已优化,分片已省略。

    在响应中,有一个像这样的 _shards 部分:

    {
        "took": 1,
        "timed_out": false,
        "_shards":{
            "total" : 1,
            "successful" : 1,
            "skipped" : 0,
            "failed" : 0
        },
        "hits":{...}
    }
    

    检查失败的分片是否有除 0 以外的任何值。如果是,请检查日志以及集群和索引状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2019-11-17
      • 2016-03-27
      相关资源
      最近更新 更多