ES 聚合后去重 精度丢失问题方案

本文探讨了在Elasticsearch中使用cardinality去重遇到误差的问题,并提供了三种解决方案:复合聚合、stats_bucket和scripted_metric。第一种方法通过组合查询减少误差,但代码复杂;第二种方法虽准确但查询时间长;第三种自定义脚本实现快速去重,但可能涉及多分片挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

  • 统计对某个字段去重后的聚合数据

  • 实现类似 sql:select count(distinct fault_name) from wangqi group by fault_name;

问题: 使用 es 的 cardinality 做数据去重 会导致 结果出现 +-%5误差;

Query:
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "rpt_dt": {
              "gte": "2022-01-01",
              "lt": "2022-12-13"
            }
          }
        }
      ]
  },
  "aggs": {
    "01": {
      "filter": {
        "terms": {
          "data_sources": [
            "01"
          ]
        }
      },
      "aggs": {
        "01": {
          "cardinality": {
            "field": "mac_id"
          }
        }
      }
    }
  }
}

Return:
{
    "01" : {
      "doc_count" : 10901762,
      "01" : {
        "value" : 1425288
      }
    }
}

 方案一:

  • 使用composite 多列聚合 类似 mysql select count(commissionamount) from xxx_table group by timeperiod,orgId
Query:
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "rpt_dt": {
              "gte": "2022-01-01",
              "lt": "2022-12-13"
            }
          }
        }
      ]
    }},
  "aggs": {
    "NAME": {
      "composite": {
        "sources": [
          {
            "fault_name": {
             "terms": {
               "field": "mac_id"
             }
            }
          },
          {
            "mac_id":{
              "terms": {
                "field": "fault_name"
              }
            }
          }
        ]
      }
    }
  }
}

Return:
{
  "key" : {
    "fault_name" : "***",
    "mac_id" : "***"
  },
  "doc_count" : 2
}
  • 通过after key 循环查询 所有返回的 fault_name 和 mac_id 排列组合,在python 中进行数量排名,去重数量计算。
  • 优点:
    • 聚合+去重结果 准确
  • 问题:
    • 需要循环查询多次(取决于排列组合数量),代码需要大量改动

方案二:

  • 使用 stats_bucket
扩大es terms 聚合size 上限
PUT test/_settings
{
  "persistent": {
    "search.max_buckets": 2000000
  }
}
GET test/_search?filter_path=aggregations.**.count,aggregations.mac_id.buckets.key,aggregations.mac_id.buckets.key_as_string
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "rpt_dt": {
              "gte": "2022-06-01",
              "lt": "2022-06-04"
            }
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "mac_id": {
        "terms": {
          "field": "rpt_dt",
          "size": 20
        },
        "aggs": {
            "fault_name": {
                "terms": {
                    "field": "mac_id",
                    "size": 100000000
                  }
            },
            "count": {
                "stats_bucket": {
                    "buckets_path": "fault_name._count"
                  }
            }
        }
    }
  }
}

具体介绍:Stats Bucket Aggregation - elasticsearch中文文档  

  • 二级聚合拿到所有二级的桶,使用 stats_bucket 统计所有桶的数量即为 去重后的数量;

  • 优点:

    • 聚合+去重结果 准确,不需要循环查询,代码改动量少
  • 问题:

    • 二级聚合拿到所有桶,比较耗时,查询时间为原始方案的 5-6倍

方案三:

使用 scripted_metric 实现自定义聚合

init_script 定义
map_script 操作 判断
combine_script 操作返回记录
reduce_script 返回sum值

Query:
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "rpt_dt": {
              "gte": "2022-06-01",
              "lt": "2022-06-04"
            }
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "mac_id": {
      "terms": {
        "field": "fault_name",
        "size": 10
      }, 
      "aggs": {
        "spu": {
          "scripted_metric": {
            "init_script": {
              "source": "state.numas=new HashMap();",
              "lang": "painless"
            },
            "map_script": {
              "source": """
              if(doc.mac_id.length>=1){
                String houseKey = doc.mac_id.value;
                state.numas.put(houseKey,1);
              }
              """,
              "lang": "painless"
            },
            "combine_script": {
              "source": """
              double item_finish_count=0;
              for(key in state.numas.keySet()){
                item_finish_count+=1;
              }
              return item_finish_count;""",
              "lang": "painless"
            },
            "reduce_script": {
              "source": """double result=0;
               for(e in states){
                if(!Objects.isNull(e)){
                    result+=e;
                }
              }
              return result;""",
              "lang": "painless"
            },
            "params": {
              "close_sum_key": "close_sum3",
              "house_sum_key": "house_sum3"
            }
          }
        }
      }
    }
  }
}

Return:
{
    "key_as_string" : "2022-06-01 00:00:00",
    "key" : 1654041600000,
    "doc_count" : 274282,
    "spu" : {
        "value" : 268144.0
    }
}
  • es 支持 scripted_metric 使用java 语法脚本的方式 自定义聚合

  • 这里使用 hashmap 数据结构,对第一层 桶做遍历,将 需要去重的字段 放入hashmap ,最后统计hashmap的key数量,得到去重后数量

  • 优点:

    • 聚合去重结果准确,代码改动少
    • 速度快,几乎和原始方案差别不到 慢20%不到
  • 缺点

    • 多分片时脚本较为复杂,因为每个分片有一个hashmap,需要汇总统计,单分片可解决
    • 天量数据可能会占用较大内存,2-3年内数据问题不大

 

<think>我们正在处理一个Elasticsearch查询需求,需要满足以下条件:1.筛选条件:a字段的值必须是'abc','bcd',或'cde'之一(即多值匹配)2.返回字段:只返回b字段,并且对b字段进行(即每个b字段的值只出现一次)3.分页:使用from和size实现分页4.后的b字段总数:在分页的同时,还需要知道后b字段的总数量(即不考虑分页,所有满足条件的b字段数量)在Elasticsearch中,如果我们想要对某个字段进行并分页,同时还要得到后的总数,我们可以使用以下两种方法:方法1:使用terms聚合(bucket)来实现,并结合bucket_sort进行分页,同时使用cardinality聚合得到总数。方法2:使用collapse功能(字段折叠)进行,然后结合普通的查询聚合来得到总数。但是,由于我们还需要分页(from和size)和总数量,这里我们选择方法1,因为collapse功能虽然可以折叠()但无法直接得到后的总数量(除非再做一个聚合),而且collapse的分页是基于折叠前的文档,可能不是我们想要的后的分页。具体思路:1.使用一个bool查询(filter)来筛选a字段的值。2.使用terms聚合来对b字段进行分组(),然后利用bucket_sort对聚合桶进行分页(排序规则需要指定)。3.同时使用cardinality聚合来得到后的b字段的总数量。注意:由于我们需要的是每个b字段的值(后)作为结果,并且要分页,所以聚合的结果会返回桶的列表,每个桶的key就是b字段的值。步骤:1.构建查询:使用boolfilter过滤a字段为'abc','bcd','cde'的文档。2.构建一个terms聚合(假设聚合名为distinct_b),字段为b,设置size为一个大数(因为我们不知道后的数量,但我们需要分页,所以先设置一个足够大的size,然后通过bucket_sort来分页?)但是这里有一个问题:terms聚合本身不支持from参数,但我们可以使用bucket_sort聚合来对聚合后的桶进行分页。因此,我们可以:-在distinct_b聚合中,设置size为足够大(比如10000),然后在其下添加一个pipelineaggregation(管道聚合)bucket_sort,在其中指定from和size。3.同时,我们在外层再添加一个cardinality聚合(假设名为total_b)来计算后的b字段的总数量。但是,这里有一个性能问题:terms聚合如果设置size很大可能会影响性能,而且我们只需要分页的那部分桶。所以,我们可以利用bucket_sort来避免先获取所有桶再分页,但是bucket_sort是在所有桶都生成后再进行排序和分页的,所以如果后的数量很大,可能会有内存问题。另一种方案Elasticsearch7.10+)是使用composite聚合,它支持分页获取聚合桶,但是这里我们还需要得到总数量,composite聚合不能直接得到总数量(需要额外的聚合)。考虑到需求中要求返回后的总数,而且还要分页,我们采用以下结构:查询结构:{"size":0,//因为我们不需要具体的文档,只需要聚合结果"query":{"bool":{"filter":[{"terms":{"a":["abc","bcd","cde"]}}]}},"aggs":{"distinct_b":{"terms":{"field":"b","size":10000//设置一个较大的值,确保能覆盖所有后的b值(如果后数量很大,这里需要谨慎)},"aggs":{"bucket_truncate":{//这个子聚合用于对桶进行排序和分页"bucket_sort":{"sort":[{"_key":{"order":"asc"}}],//按b字段的值升序排序(也可以根据需求调整)"from":0,//从第几个桶开始,由用户传入"size":10//每页桶的数量,由用户传入}}}},"total_b":{"cardinality":{"field":"b"}}}}但是,上述方法中,terms聚合的size设置得很大,如果后的b值超过10000,那么就会丢失部分数据,从而影响分页。因此,我们需要确保terms聚合的size大于等于后的总数量,而这在数据量大的时候是不可行的。改进:我们可以使用composite聚合来替代terms聚合,因为composite聚合支持分页获取聚合桶(通过after_key),而且不会像terms聚合那样受size限制。但是,composite聚合不能直接与bucket_sort一起使用,而且我们还需要同时得到总数量。因此,我们可以这样:-使用composite聚合来分页获取后的b值(每次获取一页,通过after_key翻页)-同时,使用cardinality聚合得到总数量。但是,composite聚合本身不会返回所有桶,而是每次返回一页(通过指定size),然后我们可以通过多次查询来翻页(由客户端控制)。但是,我们的一次查询只能返回一页的桶和总数。所以,我们可以这样设计:{"size":0,"query":{"bool":{"filter":[{"terms":{"a":["abc","bcd","cde"]}}]}},"aggs":{"distinct_b":{"composite":{"size":10,//每页的数量,即size"sources":[{"b":{"terms":{"field":"b"}}}]}},"total_b":{"cardinality":{"field":"b"}}}}注意:composite聚合需要指定size(即每页的桶数),并且第一次查询不需要指定after,后续查询需要根据上一次返回的after_key来翻页。但是,这样我们就能在返回中得到:-聚合distinct_b:包含一页的桶(每个桶的key就是b的值),以及一个after_key(用于下一页)。-聚合total_b:后的b的总数量。但是,这里有一个问题:composite聚合的size是控制每个分片返回的桶数,然后汇总后再返回size个桶吗?实际上,composite聚合的size是全局的,它会返回指定数量的桶(后的b值)。因此,我们可以使用composite聚合来实现分页,并且通过多次查询(每次传递after_key)来获取所有页。但是,用户要求的是在一次查询中通过from和size实现分页,而composite聚合的分页机制是通过after_key,不是from和size。然而,我们的需求中要求使用from和size,但Elasticsearch聚合分页(尤其是分页)并没有直接提供类似于from和size的参数。composite聚合的分页方式类似于游标分页,而terms聚合配合bucket_sort虽然可以指定from和size,但是需要先设置一个很大的size,这在数据量大的时候不现实。因此,我们需要权衡。考虑到Elasticsearch官方推荐使用composite聚合来处理大量数据的聚合分页,我们采用composite聚合,但是用户接口上我们可能需要调整:不使用from和size,而是使用游标(after_key)和每页大小(size)来分页。但是,问题明确要求使用from和size实现分页。那么,如果我们必须使用from和size,我们只能使用terms聚合+bucket_sort,并且设置terms聚合的size为from+size(这样我们可以获取到足够多的桶,然后截取from到from+size的桶)。但是,如果from+size很大,这个聚合可能会非常消耗内存。因此,我们有两种选择:选择1:使用terms聚合,设置size为from+size(或者更大,确保覆盖所有桶?不,我们只需要from+size个桶),然后利用bucket_sort来截取from到from+size的桶。同时,cardinality聚合单独计算总数。选择2:使用composite聚合,但模拟from和size:通过多次执行composite聚合(每次获取一页,直到达到from+size)来跳过前面的页,然后返回当前页。但是这样效率低下,尤其是在from很大的时候。考虑到性能,通常不推荐选择2。因此,如果数据量不大(即后的b值数量不是特别大,比如不超过10000),我们可以使用terms聚合+bucket_sort。假设我们允许的最大size为10000,那么我们可以这样:terms聚合的size=min(10000,from+size)//但是这样如果from+size超过10000,我们就无法获取后面的桶了。所以,如果from+size>10000,我们可能会丢失数据。因此,这种方法只适用于后数量较小的情况。如果数据量大,我们只能放弃使用from和size,而使用composite聚合的游标方式。由于问题明确要求使用from和size,并且我们无法得知用户的数据量,这里我们给出两种方案,并说明适用场景。方案一(适用于后b值数量较小,比如<=10000):使用terms聚合(设置size为10000)和bucket_sort进行分页,同时使用cardinality聚合得到总数量。方案二(适用于大数据量):使用composite聚合,但分页方式改为游标(after_key),并放弃使用from参数,而是用游标来记录位置。这样,我们无法直接跳页,但可以一页一页翻。由于问题要求使用from和size,我们先按方案一实现,但需要警告用户:如果后的b值数量超过10000,则分页可能不完整(因为terms聚合最多返回10000个桶)。如果用户需要超过10000的分页,则需要使用composite聚合。下面我们按照方案一编写查询:假设用户传递的参数:from:0//从第0个桶开始(即第一页)size:10//每页10个桶查询DSL:```json{"size":0,"query":{"bool":{"filter":[{"terms":{"a":["abc","bcd","cde"]}}]}},"aggs":{"distinct_b":{"terms":{"field":"b","size":10000,//设置一个足够大的值,确保覆盖可能的最大桶数(根据实际情况调整,这里假设10000)"order":{"_key":"asc"//按b字段的升序排列,也可以根据需求改为其他排序}},"aggs":{"bucket_truncate":{"bucket_sort":{"sort":[//这里可以留空,因为terms聚合已经按_key排序了,但也可以在这里新指定排序],"from":0,//这里应该用用户传入的from"size":10//这里应该用用户传入的size}}}},"total_b":{"cardinality":{"field":"b"}}}}```注意:bucket_sort聚合中的from和size需要根据用户传入的参数动态设置。返回结果:-聚合distinct_b中的buckets数组就是分页后的b值(每个桶的key就是b的值)。-聚合total_b的value就是后的总数量。但是,这里有一个问题:terms聚合的排序(在terms聚合内部设置的order)和bucket_sort的排序可能不一致。我们可以在terms聚合中设置按_key排序,然后在bucket_sort中不再指定排序(因为桶已经按_key排好序了),这样bucket_sort只是做截取(从from开始取size个桶)。另外,terms聚合的size设置为10000,如果后的b值超过10000,那么聚合只会返回前10000个桶(按terms聚合的排序规则),这会导致分页不完整。因此,我们需要在文档中说明这个限制。如果用户的数据量很大,我们建议使用composite聚合(游标分页),但那样就不能使用from和size了。下面给出使用composite聚合的示例(游标分页):第一次查询(第一页):```json{"size":0,"query":{"bool":{"filter":[{"terms":{"a":["abc","bcd","cde"]}}]}},"aggs":{"distinct_b":{"composite":{"size":10,//每页大小"sources":[{"b":{"terms":{"field":"b"}}}]}},"total_b":{"cardinality":{"field":"b"}}}}```返回结果中,distinct_b会包含一个buckets数组(长度为10)和一个after_key。同时,total_b给出总数。第二次查询(第二页):```json{"size":0,"query":{"bool":{"filter":[{"terms":{"a":["abc","bcd","cde"]}}]}},"aggs":{"distinct_b":{"composite":{"size":10,"sources":[{"b":{"terms":{"field":"b"}}}],"after":{"b":"上一页返回的after_key中b的值"}//注意,after_key是一个对象,如{"b":"xxx"}}},"total_b":{"cardinality":{"field":"b"}}}}```这样,我们可以实现分页,但无法直接跳页(比如从第1页跳到第5页),因为需要知道第4页的after_key。综上所述,根据用户的具体需求(要求from和size)以及数据量大小,我们给出方案一(terms+bucket_sort)作为主要方案,并提醒用户注意size限制。因此,我们最终采用方案一,但需要动态设置terms聚合的size(至少为from+size,但不超过10000)。如果用户设置的from+size>10000,我们可以将terms聚合的size设置为10000,但这样可能会导致后面的桶被截断(即无法获取from+size之后的桶)。所以,我们最好在terms聚合的size中设置一个最大值(比如10000),然后如果用户需要的from+size大于这个最大值,则返回错误或警告。在实际应用中,我们可以这样:terms_size=Math.min(MAX_TERMS_SIZE,from+size);然后设置terms聚合的size为terms_size,而bucket_sort的from和size用用户传入的值。但是,如果from+size>MAX_TERMS_SIZE,我们只能返回前MAX_TERMS_SIZE个桶,然后bucket_sort从from开始取size个桶时,如果from已经超过了实际返回的桶数(terms_size),那么返回的桶就是空的。因此,我们需要在程序中进行判断:如果用户传入的from+size>MAX_TERMS_SIZE,则提示用户分页超出范围。考虑到这些,我们给出最终的查询DSL(假设MAX_TERMS_SIZE=10000):用户传入:from=0,size=10则terms聚合的size=min(10000,0+10)=10用户传入:from=9990,size=20则terms聚合的size=min(10000,9990+20)=10000(因为10100>10000,所以取10000)然后bucket_sort的from=9990,size=20,这样会返回10000个桶中的第9990到10000(因为只有10000个桶,所以只能返回10个桶)?注意:bucket_sort的from是相对于聚合桶的起始位置,而聚合桶最多10000个,所以当from=9990时,只能返回10个桶(因为桶总数是10000,所以从9990开始只能取到第10000个,即10个桶)。所以,我们能够返回正确的分页,但是用户可能期望的是20个桶,而实际只返回了10个桶(因为已经到末尾了)。这符合分页的常规逻辑(最后一页可能不足size)。因此,我们可以这样构建查询:参数:letpageSize=size;//每页桶数letfrom=from;//从第几个桶开始(基于0)lettermsSize=Math.min(MAX_TERMS_SIZE,from+size);查询DSL:```json{"size":0,"query":{"bool":{"filter":[{"terms":{"a":["abc","bcd","cde"]}}]}},"aggs":{"distinct_b":{"terms":{"field":"b","size":termsSize,//动态计算"order":{"_key":"asc"}},"aggs":{"bucket_truncate":{"bucket_sort":{"sort":[//可留空,因为terms已经按_key排序],"from":from,"size":size}}}},"total_b":{"cardinality":{"field":"b"}}}}```返回结果中,从聚合distinct_b的buckets中获取分页后的b值列表,从total_b的value中获取总数。注意:由于terms聚合的size设置为termsSize(即from+size,但不超过MAX_TERMS_SIZE),所以如果后的b字段总数大于termsSize,那么聚合桶的数量最多为termsSize,因此我们得到的桶是不完整的(即只有前termsSize个桶,按排序规则)。所以,总数量total_b的值可能大于termsSize,但是我们在分页桶中只能展示最多termsSize个桶。所以,用户看到的分页桶数最多为termsSize,而总数total_b是真实的数量。因此,在分页展示时,我们返回:-当前页的b值列表(来自distinct_b.buckets)-后的总数量(total_b.value)-注意:分页的最大桶数受限于termsSize,所以如果from超过termsSize,则返回空列表。最后,我们还需要注意字段b的数据类型,必须是keyword类型(或者text类型,但text类型需要设置fielddata=true,但通常不建议,最好用keyword子字段)。如果b是text类型,那么通常我们会用b.keyword。假设b字段是keyword类型,那么我们可以直接用。如果是text类型,我们需要使用b.keyword(如果存在的话)。因此,在field中,我们应该使用正确的字段名,比如"b"或"b.keyword"。综上所述,我们构建了满足需求的Elasticsearch查询。下面是一个完整的示例(假设b字段为keyword类型,且MAX_TERMS_SIZE=10000):用户需求:筛选a字段为'abc','bcd','cde',返回b字段后的分页结果(每页10条,第1页),并返回后的总数。查询DSL:```json{"size":0,"query":{"bool":{"filter":[{"terms":{"a":["abc","bcd","cde"]}}]}},"aggs":{"distinct_b":{"terms":{"field":"b","size":10000,//这里我们设置10000,因为from=0,size=10,所以termsSize=10,但我们可以直接设置10000(因为0+10<10000)"order":{"_key":"asc"}},"aggs":{"bucket_truncate":{"bucket_sort":{"from":0,"size":10}}}},"total_b":{"cardinality":{"field":"b"}}}}```返回结果解析:-在聚合distinct_b的buckets数组中,有10个桶(如果满足条件的b值有至少10个的话),每个桶的key就是b的值。-在聚合total_b的value中,就是后的总数量。注意:由于我们设置了terms聚合的size为10000,所以最多返回10000个桶,然后bucket_truncate会从中取第0到第10个桶(即第一页10条)。如果用户要查询第100页(即from=990,size=10),那么bucket_truncate的from=990,size=10,会从10000个桶中取第990到1000个桶(前提是桶的数量>=1000)。因此,这个查询可以满足需求。但是,请注意:这个查询在数据量大的时候(后的b值很多)可能会占用大量内存,因为terms聚合会返回最多10000个桶。如果数据量非常大,建议使用composite聚合的游标分页,但游标分页不支持任意跳页。最后,我们还需要注意:如果用户不需要分页,而是需要所有后的b值,那么我们可以使用更简单的方式(比如设置size=10000,然后不使用bucket_sort,但同样受限于10000)。因此,根据实际需求,我们提供了使用terms聚合和bucket_sort实现的分页查询。希望这个回答能够解决你的问题。相关问题:1.在Elasticsearch中,除了使用terms聚合和bucket_sort,还有哪些方式可以实现字段并分页?2.使用composite聚合进行分页时,如何获取字段的总数量?3.Elasticsearch的cardinality聚合精度如何?能否保证100%准确?4.如果字段b是text类型,如何实现聚合?</think>### Elasticsearch查询解决方案Elasticsearch中实现您的需求(筛选`a`字段值为`'abc'`、`'bcd'`或`'cde'`的文档,返回后的`b`字段并分页,同时获取总数),可通过组合以下技术实现: #### 完整查询DSL ```json { "size": 0, // 不返回原始文档 "query": { "bool": { "filter": [ { "terms": { "a": ["abc", "bcd", "cde"] // 筛选a字段值 } } ] } }, "aggs": { "distinct_b": { "composite": { "size": 10, // 每页数量 "sources": [ { "b_value": { "terms": {"field": "b"} // 对b字段 } } ] } }, "total_count": { "cardinality": { "field": "b" // 计算总数 } } }, "from": 0 // 分页起始位置 } ``` #### 关键组件说明 1. **筛选条件** ```json "terms": { "a": ["abc", "bcd", "cde"] } ``` 使用`terms`查询匹配`a`字段的多值条件。 2. **分页** ```json "composite": { "size": 10, "sources": [{ "b_value": { "terms": {"field": "b"} }] } ``` - `composite`聚合实现分页 - `size`控制每页返回的值数量 - `b_value`存储后的`b`字段值 3. **总数统计** ```json "cardinality": { "field": "b" } ``` 独立计算总数(不受分页影响) 4. **分页控制** ```json "from": 0 // 替换为实际偏移量 ``` 通过修改`from`值实现分页跳转(需配合游标优化) #### 结果解析 - **值列表**:`aggregations.distinct_b.buckets[].key.b_value` - **总数**:`aggregations.total_count.value` - **下一页游标**:`aggregations.distinct_b.after_key`(用于深度分页) #### 游标分页优化 当`from`值较大时(如超过10,000),建议改用游标分页: ```json "composite": { "size": 10, "sources": [...], "after": {"b": "上一页最后值"} // 添加游标 } ``` #### 注意事项 1. **字段类型要求** `b`字段需为`keyword`类型,若为`text`类型需改用`b.keyword` 2. **性能影响** `cardinality`聚合有±5%精度误差(可通过`precision_threshold`调整) 3. **最大桶数限制** 默认返回100个桶,需在`elasticsearch.yml`中调整: ```yml search.max_buckets: 10000 ``` > **要提示**:当处理超大数据集时,推荐改用`search_after`参数实现深度分页[^1]。 ### 示例场景 - **第1页请求**:`from=0`, `size=10` - **第2页请求**:将`from`改为`10`,或使用`after_key` - **结果总数**:始终通过`total_count.value`获取 ### 相关问题 1. 如何优化Elasticsearch深度分页的性能? 2. `cardinality`聚合精度误差如何修正? 3. 当需要同时返回其他聚合结果时,查询结构应如何调整? 4. Elasticsearch中`keyword`和`text`类型在聚合时的区别是什么? 5. 如何监控大型聚合查询的资源消耗? [^1]: 引用[1]:102.HR.DEPARTMENTS表是HR.EMPLOYEES表的父级...具有ON DELETE CASCADE选项...(演示引用示例) [^2]: 引用[2]:消息: 描述: 300 Multiple Choices...(状态码参考)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值