首页 > 解决方案 > 用于分页聚合的 Elasticsearch From 和 Size

问题描述

首先,我想说我想要达到的要求在 SOLR 5.3.1 上运行良好,但在 AWS 上的 ElasticSearch 6.2 上运行良好。

我的实际查询非常大且复杂,它在 kibana 上运行良好,但当我越过from = 100size = 50时却不行,因为它在 kibana 控制台上显示错误,

我知道的:

对于普通搜索,最大from可以是10000,对于聚合搜索,最大from可以是100

如果我超过了这个限制,那么我必须更改最大限制,这是不可能的,因为我在 AWS 上使用 ES 作为服务,或者我使用具有滚动 ID 功能的滚动API 来获取分页数据。

Scroll API 工作正常,因为我已经将它用于项目的另一部分,但是当我尝试使用聚合的相同 Scroll 时,它没有按预期工作。

这里使用 Scroll API,第一次搜索获取聚合数据,但第二次使用滚动 id 调用不返回聚合结果,仅显示Hits结果

Kibana 上的查询

GET /properties/_search
{
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "published": true
          }
        },
        {
          "match": {
            "country": "South Africa"
          }
        }
      ]
    }
  },
  "aggs": {
    "aggs_by_feed": {
      "terms": {
        "field": "feed",
        "order": {
          "_key": "desc"
        }
      },
      "aggs": {
        "tops": {
          "top_hits": {
            from: 100,
            size: 50,
            "_source": [
              "id",
              "feed_provider_id"
            ]
          }
        }
      }
    }
  },
  "sort": [
    {
      "instant_book": {
        "order": "desc"
      }
    }
  ]
}

在 python 上搜索:我在此搜索中面临的问题是,第一次搜索获取聚合数据以及命中数据,但对于下一次使用滚动 ID 调用,它不会返回仅显示命中数据的聚合数据。

if index_name is not None and doc_type is not None and body is not None:
   es = init_es()
   page = es.search(index_name,doc_type,scroll = '30s',size = 10, body = body)
   sid = page['_scroll_id']
   scroll_size = page['hits']['total']

   # Start scrolling
   while (scroll_size > 0):

       print("Scrolling...")
       page = es.scroll(scroll_id=sid, scroll='30s')
       # Update the scroll ID
       sid = page['_scroll_id']

       print("scroll id: " + sid)

       # Get the number of results that we returned in the last scroll
       scroll_size = len(page['hits']['hits'])
       print("scroll size: " + str(scroll_size))

       print("scrolled data :" )
       print(page['aggregations'])

在 python 上使用 Elasticsearch-DSL:使用这种方法,我正在努力选择第二个 aggs ig tops->top_hits 之类的_source字段名称idfeed_provider_id

es = init_es()
    s = Search(using=es, index=index_name,doc_type=doc_type)

    s.aggs.bucket('aggs_by_feed', 'terms', field='feed').metric('top','top_hits',field = 'id')
    response = s.execute()
    print('Hit........')
    for hit in response:
        print(hit.meta.score, hit.feed)
    print(response.aggregations.aggs_by_feed)
    print('AGG........')
    for tag in response.aggregations.aggs_by_feed:
        print(tag)

所以我的问题是

对于 from=100 以上的聚合查询,是否无法使用fromsize字段获取数据?

如果可能的话,请用普通的elasticsearch方式或elasticsearch-dsl python方式给我一个提示,因为我对elasticsearch-dsl和elasticsearch bucket,matric等并不熟悉。

关于 SO 的一些答案告诉使用分区,但我不知道如何在我的场景中使用它如何使用 From / Size 控制弹性搜索聚合结果?

其他一些人说 ES 当前不支持此功能(目前在功能请求中)。如果这不可能,还有什么可以代替 Solr 中的分组?

标签: elasticsearchelasticsearch-aggregationelasticsearch-dslelasticsearch-dsl-py

解决方案


推荐阅读