ElasticSearch6 Java 搜索查询、聚合分析

导读:本篇文章讲解 ElasticSearch6 Java 搜索查询、聚合分析,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

前言:

ES中的搜索查询,简单说就是根据查询条件匹配查询结果。网上的例子比较简单,这里我以一个比较复杂的DSL结构化查询语句为例子,看看用java的API如何描述这个查询语句。
其中涉及组合查询、聚合查询。

建议:

最好先下载一份ES的Java最新的API,对照着看效果会比较棒。

1、建立连接:

java连接ES集群的方式还挺多,最常用的应该是TransportClient。
它作为一个外部访问者,请求ES的集群,对于集群而言,它是一个外部因素。

Settings	esSettings   =	Settings.builder()
				.put("cluster.name",	clusterName)	//设置ES实例的名称
				.put("client.transport.sniff",	true)	//自动嗅探整个集群的状态, 把集群中其他ES节点的ip添加到本地的客户端列表中
				.build();
				client	=	new	PreBuiltTransportClient(esSettings);//初始化clie nt较老版本发生了变化,此方法有几个重载方法,初始化插件等。
				//此步骤添加IP,至少一个,其实一个就够了,因为添加了自动嗅探配置
				client.addTransportAddress(new	InetSocketTransportAddress(In etAddress.getByName(ip),	esPort));

注意,Java连接集群的端口一般是9300,HTTP端口一般是9200,集群名一定要设置正确。

2、组合查询:

这里我们将用Java的API描述这样一个DSL查询:
这个查询主要是查询某个索引,需要满足以下条件:
(1)logtime是一个描述时间的字段,他需要满足我们传入的开始时间和结束时间之间,这样一个时间段;
(2)kpi_code字段不能是“1111”、“2222”;
(3)asset是一个数组字段里面存储多个IP,我们需要模糊匹配我们传入的一个IP,即asset数组中需要包含我们传入的IP;
(4)is_steal字段严格匹配“1”;
(5)最后是一个聚合分析,按照指定的格式返回查询;

看不明白DSL的可以去补充一下,DSL查询,使用JAVA基本上就是把DSL语句描述出来。

:{
       "size":0,
       "query":{
          "bool": {
              "filter": [
                           {
                        "bool": {
                          "must": [                         
                             {
                               "range": {
                                   "logtime": {
                                        "gte": TOOL.moment(startday).format("YYYY-MM-DD")+"T00:00:00",
                                        "lte": TOOL.moment(endday).format("YYYY-MM-DD")+"T23:59:59",
                                        "include_lower": true,
                                        "include_upper": true,
                                        "boost": 1,
                                        "time_zone": "+08:00"
                                                    }
                                        }
                              },
                              {
                                "bool": {
                                    "must_not": [
                                        {
                                            "match_phrase": {
                                                "kpi_code": {
                                                    "query": "3086",
                                                    "slop": 0,
                                                    "boost": 1
                                                }
                                            }
                                        }
                                    ],
                                    "adjust_pure_negative": true,
                                    "boost": 1
                                }
                             },
                             {
                                "bool": {
                                    "must_not": [
                                        {
                                            "match_phrase": {
                                                "kpi_code": {
                                                    "query": "3087",
                                                    "slop": 0,
                                                    "boost": 1
                                                }
                                            }
                                        }
                                    ],
                                    "adjust_pure_negative": true,
                                    "boost": 1
                                }
                              },
                              {
                                "wildcard": {
                                    "asset": {
                                        "wildcard": "*"+ip+"*",
                                        "boost": 1
                                    }
                                }
                              },
                              {
                                "bool": {
                                  "must": [
                                    {
                                      "term": {
                                        "is_steal": "1"
                                        
                                      }
                                    }                                                                  
                                  ],
                                  "adjust_pure_negative": true,
                                  "boost": 1
                                }
                              }                             
                          ],
                          "adjust_pure_negative": true,
                          "boost": 1
                        }
                         }
                       ]
                    }
      },
      "aggs":{
            "gid":{
                "terms":{"script": "return doc['logtime'].value+','+doc['gid'].value+','+doc['kpi_code'].value+','+doc['steal_stage'].value+','+doc['malname.keyword'].value+','+doc['event_level'].value","size":10000,"order":[{"_key": "asc"}]}
             }
           }  
      }
  }) 

搜索查询使用的是SearchResponse,其主要工作在于如何构建查询器、聚合器。

/**
	 * 从ES中根据指定条件查询
	 * @param index					索引名
	 * @param query					查询器
	 * @param aggregation                           聚合器
	 * @return
	 */
	
	public Aggregations searchFunction(String index, QueryBuilder query, AggregationBuilder aggregation){
		
		SearchResponse response = this.client.prepareSearch(index)
									.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
									.setQuery(query)
									.addAggregation(aggregation)
									.setFrom(0)
									.setSize(0).setExplain(true).get();
									
		//SearchHits hits = response.getHits();
		Aggregations aggregations = response.getAggregations();
		
		return aggregations;
	}

search查询的语句基本就是这样,我们需要传入构建好的QueryBuilder 、AggregationBuilder ,就OK了。
下面重点说一下,QueryBuilder 和AggregationBuilder 的构建。

3、构建查询条件:

先贴出代码:

//嵌套查询
			BoolQueryBuilder childQb1 = QueryBuilders.boolQuery();
			childQb1.mustNot(QueryBuilders.matchPhraseQuery("kpi_code", "3086"));
		
			BoolQueryBuilder childQb2 = QueryBuilders.boolQuery();
			childQb2.mustNot(QueryBuilders.matchPhraseQuery("kpi_code", "3087"));
		
			WildcardQueryBuilder childQb3= QueryBuilders.wildcardQuery("asset", "*"+ip+"*");
		
			BoolQueryBuilder childQb4 = QueryBuilders.boolQuery();
			childQb4.must(QueryBuilders.termQuery("is_steal", "1"));
		
			RangeQueryBuilder rangeBuilder = new RangeQueryBuilder("logtime")
											.gte(startDay+"T00:00:00").lte(endDay+"T23:59:59")
											.timeZone("+08:00");
		
			BoolQueryBuilder qb = QueryBuilders.boolQuery();
			qb.filter(rangeBuilder).filter(childQb1).filter(childQb2).filter(childQb3).filter(childQb4);
		
			//嵌套聚合
			Script script = new Script("return doc['logtime'].value+','+doc['gid'].value+','+doc['kpi_code'].value+','+doc['steal_stage'].value+','+doc['malname.keyword'].value+','+doc['event_level'].value");
			TermsAggregationBuilder aggresstionTwo = AggregationBuilders.terms("gid").script(script);
			aggresstionTwo.size(10000);
			//aggresstionTwo.order(BucketOrder.aggregation("_key", true));
				
			Aggregations aggresstions = esUtil.searchFunction("jg_gaojing*", qb, aggresstionTwo);		

嵌套查询中的BoolQueryBuilder 是最常用的。我们看到,对应DSL的每个查询命令都有对应。我建议从最里层的“bool”开始写,一层层嵌套直至最外层。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/10356.html

(0)
小半的头像小半

相关推荐

极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!