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啦~
是不是比聚合后去重在分页简单多了???