elasticsearch RestHighLevelClient 关于document的常用操作 ---------- 查询篇
在es中查询大致分为两类:普通查询、复杂查询。
普通查询只需要使用:GetRequest即可
复杂查询涉及很多:
SearchSourceBuilder(用于指定搜索条件时的附加条件:排序、分页、查询范围、展示\屏蔽字段、各种常见聚合查询等)
QueryBuilders(用于指定搜索模式:全量搜索、附加单条件搜索、附加多条件搜索、模糊搜索等)
SearchRequest(用于指定被操作的索引、加载搜索条件等操作)
es单条操作--查询文档
public String findEsDocument(){ //创建查询文档请求 GetRequest getRequest = new GetRequest(); //设置属性 getRequest.index("user").id("sAMC7XgBrgVVHTXvmYL_"); try { //像es服务发送请求 GetResponse findInfo = this.client.get(getRequest, RequestOptions.DEFAULT); System.out.println("find es index _index is : " + findInfo.getIndex()); System.out.println("find es index _id is : " + findInfo.getId()); System.out.println("find es index _type is : " + findInfo.getType()); System.out.println("find es index source is : " + findInfo.getSourceAsString()); } catch (IOException e) { e.printStackTrace(); } return "find es index complete"; }
es批量查询--全量查询操作
特别注意:
无论是什么样的搜索一定要一定要加分页来指定page和pageSize的大小。因为es中matchAllQUery()和MatchQueryBuilder()的默认检索量是10条。page一定要指定为0因为0在es中是初始默认页。
public String findAll(){ //设置搜索类型及条件 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//新建搜索 searchSourceBuilder.query(QueryBuilders.matchAllQuery());//指定全量搜索 searchSourceBuilder.from(0);//指定page searchSourceBuilder.size(5);//指定pageSize searchSourceBuilder.sort("age" , SortOrder.ASC);//排序规则 //创建检索文档请求 SearchRequest request = new SearchRequest(); request.indices("user");//指定索引名称 request.source(searchSourceBuilder);//加载搜索条件 SearchResponse search = null; try { search = this.client.search(request, RequestOptions.DEFAULT); } catch (IOException e) { e.printStackTrace(); } SearchHit[] hits = search.getHits().getHits(); List<Map<String , Object>> list = new ArrayList<>(); for(SearchHit value : hits){ String sourceAsString = value.getSourceAsString(); JSONObject jsonObject = JSONObject.parseObject(sourceAsString); HashMap<String, Object> map = new HashMap<>(); map.put("id" , value.getId());//获取当前索引的主键ID map.put("userName" , jsonObject.getString("userName")); map.put("age" , jsonObject.getString("age")); map.put("sex" , jsonObject.getString("sex")); list.add(map); } for (Map<String , Object> listValues : list){ Set<Map.Entry<String, Object>> entries = listValues.entrySet(); for (Map.Entry<String , Object> mapValues : entries){ System.out.println("key : " + mapValues.getKey() + " value : " + mapValues.getValue()); } } return "match all query es is complete"; }
es批量查询--全量单条件查询操作
public String findAllByTerm(){ //构建搜索条件以及一些其它参数配置 SearchSourceBuilder builder = new SearchSourceBuilder(); //设置查询条件(where) TermQueryBuilder queryWhere = QueryBuilders.termQuery("userName.keyword", "张三"); builder.query(queryWhere);///对于未分词的字符串类型的检索一定要表示keyword关键字 //设置查询范围(range) RangeQueryBuilder queryRangeByAge = QueryBuilders.rangeQuery("age"); queryRangeByAge.gte("40"); queryRangeByAge.lte("300"); builder.query(queryRangeByAge); //设置分页 builder.from(0); builder.size(5); //设置排序 builder.sort("age" , SortOrder.DESC); //设置要展示/屏蔽的字段 String[] excludes = {}; String[] includes = {"userName" , "lastName" , "age"}; builder.fetchSource(includes , excludes); //指定要检索的索引并装载搜索条件及各项属性设置 SearchRequest request = new SearchRequest(); request.indices("user"); request.source(builder); //发送查询请求 SearchResponse search = null; try { search = this.client.search(request, RequestOptions.DEFAULT); } catch (IOException e) { e.printStackTrace(); } return "term query es is complete"; }
复杂的bool查询操作及常见聚合操作
public String BoolEsDocument(){ //指定搜索条件 should == or must == and BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.should(QueryBuilders.termQuery("education.keyword" , "高中")); boolQueryBuilder.should(QueryBuilders.termQuery("education.keyword" , "本科")); boolQueryBuilder.must(QueryBuilders.termQuery("sex.keyword" , "女")); //指定范围查询 == between RangeQueryBuilder rangeQueryBuilderByAge = QueryBuilders.rangeQuery("age"); rangeQueryBuilderByAge.lte(100); rangeQueryBuilderByAge.gte(10); RangeQueryBuilder rangeQueryBuilderByHeight = QueryBuilders.rangeQuery("height"); rangeQueryBuilderByHeight.lte(200); rangeQueryBuilderByHeight.gte(190); //模糊查询 WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("userName.keyword" , "*" + "r" + "*"); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(boolQueryBuilder);//加载and or搜索条件 builder.query(rangeQueryBuilderByAge);//加载范围查找搜索条件 builder.query(rangeQueryBuilderByHeight);//加载范围查找搜索条件 builder.query(wildcardQueryBuilder);//加载模糊查询搜索条件 builder.from(0);//起始页 builder.size(5);//每页记录数 builder.sort("age" , SortOrder.ASC);//排序 String[] excludes = {};//需要屏蔽的字段 String[] includes = {"userName" , "age" , "education" , "sex"};//需要展示的字段 builder.fetchSource(includes , excludes);//加载屏蔽/展示字段 //count ValueCountAggregationBuilder field = AggregationBuilders.count("count_user_name").field("userName.keyword"); builder.aggregation(field); //avg AvgAggregationBuilder avg_age = AggregationBuilders.avg("avg_age").field("age"); builder.aggregation(avg_age); //Cardinality 去重的统计 CardinalityAggregationBuilder cardinality_sex = AggregationBuilders.cardinality("cardinality_sex").field("sex.keyword"); builder.aggregation(cardinality_sex); //sum SumAggregationBuilder sum_total_score = AggregationBuilders.sum("sum_total_score").field("totalScore"); builder.aggregation(sum_total_score); //max MaxAggregationBuilder max_height = AggregationBuilders.max("max_height").field("height"); builder.aggregation(max_height); //min MinAggregationBuilder min_weight = AggregationBuilders.min("min_weight").field("weight"); builder.aggregation(min_weight); SearchRequest request = new SearchRequest(); request.indices("user"); request.source(builder); SearchResponse search = null; try { search = this.client.search(request, RequestOptions.DEFAULT); } catch (IOException e) { e.printStackTrace(); } if(search.status() == RestStatus.OK){ SearchHit[] hits = search.getHits().getHits(); for (SearchHit hitsValue : hits){ String sourceAsString = hitsValue.getSourceAsString(); JSONObject jsonObject = JSONObject.parseObject(sourceAsString); System.out.println("userName : " + jsonObject.getString("userName") + "sex : " + jsonObject.getString("sex") + " age : " + jsonObject.getString("age") + " lastName : " + jsonObject.getString("lastName") + " height : " + jsonObject.getString("height") + " weight : " + jsonObject.getString("weight") + " education : " + jsonObject.getString("education") + " totalScore : " + jsonObject.getString("totalScore")); } Aggregations aggregations = search.getAggregations(); ValueCount count_user_name = aggregations.get("count_user_name"); System.out.println("count_user_name : " + count_user_name.getValue()); Avg avg_age_result = aggregations.get("avg_age"); System.out.println("avg_age : " + Math.round(avg_age_result.getValue())); Cardinality cardinality_sex_result = aggregations.get("cardinality_sex"); System.out.println("cardinality_sex : " + cardinality_sex_result.getValue()); Sum sum_total_score_result = aggregations.get("sum_total_score"); System.out.println("sum_total_score : " + sum_total_score_result.getValue()); Max max_height_result = aggregations.get("max_height"); System.out.println("max_height : " + max_height_result.getValue()); Min min_weight_result = aggregations.get("min_weight"); System.out.println("min_weight : " + min_weight_result.getValue()); } return "bool query es document is complete2"; }
特殊情况:
针对map数据类型的自定义条件查询
map数据类型在做查询操作时比较特别须写全标识,示例中scoure为字段归属标识,“数学”为字段名,keyword为分词,99为值
个人猜想此处须单独写出scoure字段归属标识有两个原因:1.此处查询操作的条件是完全脱离实体类进行设置的。2.考虑到字段同名问题须特别指出要修改哪个“数学”
public void mapTestSelect(){ BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); boolQueryBuilder.must(QueryBuilders.termQuery("userName.keyword" , "李四")); boolQueryBuilder.must(QueryBuilders.termQuery("scoure.历史.keyword" , "99")); SearchSourceBuilder builder = new SearchSourceBuilder(); builder.query(boolQueryBuilder);//加载and or搜索条件 SearchRequest request = new SearchRequest(); request.indices("map_test"); request.source(builder); SearchResponse search = null; Person personInfo = new Person(); try { search = this.client.search(request, RequestOptions.DEFAULT); SearchHit[] hits = search.getHits().getHits(); for (SearchHit value : hits){ String sourceAsString = value.getSourceAsString(); personInfo = JSONObject.parseObject(sourceAsString , Person.class); } System.out.println("personInfo = " + personInfo); System.out.println("personInfo.getAge() = " + personInfo.getAge()); System.out.println("personInfo.getScoure().get(\"数学\") = " + personInfo.getScoure().get("数学")); } catch (IOException e) { e.printStackTrace(); } }