es 使用 cardinality + collapse做分页去重查询

本文介绍了Elasticsearch中cardinality用于计算字段值的唯一数量,以及collapse字段折叠功能用于去重。这两个特性可以结合使用,提供分页查询时的去重结果。示例展示了如何在查询语句中结合使用这两个功能,以实现更高效的分页处理。
摘要由CSDN通过智能技术生成

1.首先我们来介绍一下cardinality的用法

cardinality 即去重计算,类似sql中 count(distinct),先去重再求和,计算指定field值的种类数。

GET/index/_search
{
  "size":0,
  "query": {
    "match_all": {}
  }
  "aggs": {
    "test_count": {
      "cardinality": {
        "field": "name"
      }
    }
  }
}

//返回结果
{
  //...
  "aggregations": {
    "test_count": {
      "value": 5
    }
  }
}

可以看到,aggregations聚合下,返回了按名字查询去重后的结果数,但是只有去重后的条数,没有具体的数据。

2.接下来我们再看一下collapse的用法

collapse是es5以后的新特性collapse ,Field Collapsing(字段折叠)不能与scroll、rescore以及search after 结合使用。

优点:简单,性能好。
注意:collapse的字段需要为keyword或者number类型。
示例:

GET /index/_search
{
    "query": {
        "match": {
            "message": "elasticsearch"
        }
    },
    "collapse" : {
        "field" : "user" 
    }
}



//返回结果
{
	"hits": {
		"total": 2,
		"max_score": 4.276666,
		"hits": [{
			"_index": "index",
			"_type": "type",
			"_id": "kiRgoHsBtpTqY8pwLiMi",
			"_score": 4.276666,
			"_source": {
				//数据展示
			},
			"fields": {
				"message: [
					"elasticsearch"
				]
			}
		}]
	}
}

这里可以看到,我们使用collapse对查询数据进行去重后的结果,刚好与cardinality返回的总条数完美结合,构成了分页必备的条件。

3,实战演示

下面我们随便写一个查询语句,将两者结合起来

{
    "query": {
        "bool": {
            "filter": [
                {
                    "range": {
                        "personid": {
                            "lt": "1000000000"
                        }
                    }
                },
                {
                    "bool": {
                        "should": [],
                        "minimum_should_match": 1
                    }
                },
                {
                    "term": {
                        "isDeleted": "0"
                    }
                }
            ]
        }
    },
    "collapse": {
        "field": "course_id"
    },
    "from": 0,
    "size": 10,
    "track_total_hits": true,
    "aggs": {
      "courseAgg": {
        "cardinality": {
          "field": "course_id"
        }
      }
    }
}

返回结果如下

{
  "took" : 140,
  "timed_out" : false,
  "_shards" : {
    "total" : 6,
    "successful" : 6,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2111,
      "relation" : "eq"
    },
    "max_score" : 0.0,
    "hits" : [...]
  },
  "aggregations" : {
    "courseAgg" : {
      "value" : 1070
    }
  }
}

解释说明:

1.hits中total的总条数实际上是去重前的总条数,原数据条数,这里我们知道就行,分页中我们并不使用它。hits中数组的大小刚好等于courseAgg聚合的值,数组中的数据就是去重后的数据。

2.aggregations中的courseAgg条数,这个才是去重后的实际条数,也是分页用的总条数。

3.from 查询的偏移量,也就是从哪里开始查。

4.size 查询条数,一次查几条。

接下来,你就可以把它当做一个简单分页查询来用了,传入from和size就ok啦~

是不是比聚合后去重在分页简单多了???

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值