当前位置:   article > 正文

elasticsearch去重查询_define your query using query dsl 去重复

define your query using query dsl 去重复

elasticsearch去重查询

目录:
1、业务背景:
2、切入正题:去重查询

1、业务背景:

最近的实际中业务中,要对用户订单数据进行统计,用户订单数据从用户下单到支付的过程都会记录,同时每次用户订单查看也会产生一次订单更新数据,但是由于历史原因,用户订单更新数据入库没有进行整理,都是直接把订单相关的数据存入es。今天某项数据分析需要对用户订单进行查询并去重做一些针对订单维度的分析。

2、切入正题:去重查询

2.1、关系型数据库处理

一般关系型数据库去重统计直接sql中的distinct函数就可以实现,

获取统计去重后的数量:

select distinct(count(1)) from order;
  • 1

获取去重后的结果:

select distinct order_id from order;
  • 1
2.2、es中查询处理方法

获取统计去重后的数量一般使用Cardinality聚合函数,DSL样例如下:

GET /index_name/_search
{
	"size": 1,
	"_source": {
		"includes": ["设置需要的返回字段"],
		"excludes": []
	},
	"query": {
		"bool": {
			"设置查询条件": "使用term/terms/filter等"
		}
	},
	"aggregations": {
		"cardinality_field": {
			"cardinality": {
				"field": "设置根据哪个字段进行去重"
			}
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

上述DSL执行返回:

{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": null,
    "hits": [
      
    ]
  },
  "aggregations": {
    "cardinality_field": {
      "value": 1
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

从执行结果可以看到,查询结果是3条数据,通过某字段进行聚合去重后只有一条符合,同时我们也发现通过这样 Cardinality 聚合函数我不知道具体是那条数据符合要求。

Java-api使用:

jar包:

<!-- https://mvnrepository.com/artifact/org.elasticsearch.client/transport -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>transport</artifactId>
    <version>根据自己使用版本设置</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Java代码:

//构造DSL
 cardinalityBuilder = AggregationBuilders.cardinality("uid_aggs").field("orderId");
SearchRequestBuilder request = client.prepareSearch("XXXX")
		.setTypes("XXX")
		.setSearchType(SearchType.QUERY_THEN_FETCH)
		.setQuery(QueryBuilders.boolQuery()
				.must(QueryBuilders.termQuery("orderId", "")))
		.addAggregation(cardinalityBuilder)
		.setSize(1);
//获取返回结果		
SearchResponse response = request.execute().actionGet();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

获取去重后的结果:5.3版本之前只有top_hits聚合,但5.3以上的版本仍然可用,DSL如下:

POST /index_name/
{
	"size": 0,
	"query": {
		"bool": {

		}
	},
	"aggregations": {
		"uid_top": {
			"top_hits": {
				"sort": [{
					"orderId": {
						"order": "desc"
					}
				}],
				"size": 1,
				"_source": {
					"includes": [
						"orderId"
					],
					"excludes": []
				}
			}
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

上述DSL中我对去重后的结果返回字段进行了设置,执行返回:

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "uid_top": {
      "hits": {
        "total": 3,
        "max_score": null,
        "hits": [
          {
            "_index": "",
            "_id": "",
            "_score": null,
            "_source": {
              "order_id": ""
            },
            "sort": [
              ""
            ]
          }
        ]
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

java-api参考:

//在聚合中进行设置:
AggregationBuilder aggregationBuilder = AggregationBuilders.terms("orderId_aggs").field("orderId").size(10000).subAggregation(AggregationBuilders.topHits("uid_top").addSort("offline_time", SortOrder.DESC).setSize(1));
  • 1
  • 2
注意:

es5.3版本以上,新增了字段折叠(Field Collapsing)功能,所谓的字段折叠理解就是按特定字段进行合并去重,DSL样例如下:

{
	"size": 100,
	"query": {
		"设置查询条件"
	},
	"collapse": {
		"field": "orderId"
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

上述DSL执行返回的结果中会把重复的数据直接过滤调,相同的数据只会返回一条,这样有利于后续其他的维度分析。

java-api参考:

CollapseBuilder collapseBuilder = new CollapseBuilder("orderId");
    
SearchRequestBuilder requestBuilder = transportClient.prepareSearch("XXX").setTypes("XXX")
                .setSize(111).setQuery(queryBuilder).setCollapse(collapseBuilder);
  • 1
  • 2
  • 3
  • 4
结尾:

到这里我个人对 elasticsearch 去重查询的基本总结结束了,欢迎大家留言批评指正。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/777426
推荐阅读
相关标签
  

闽ICP备14008679号