当前位置:   article > 正文

Elasticsearch查询以及聚合查询_es 过滤后分组

es 过滤后分组

1、条件查询 bool

must:返回的文档必须满足子句的条件,并且参与计算分值
filter:返回的文档必须满足filter子句的条件,不会参与计算分值
should:返回的文档可能满足should子句的条件。
must_nout:返回的文档必须不满足must_not定义的条件。
注意:如果一个查询既有filter又有should,那么至少包含一个should子句。

bool 查询

user 值为kimchy tag 值为tech

"query": {
   "bool" : {
        "must" : {
            "term" : { "user" : "kimchy" }
        },
        "filter": {
            "term" : { "tag" : "tech" }
        },
        "must_not" : {
            "range" : {
                "age" : { "from" : 10, "to" : 20 }
            }
        },
        "should" : [
            {"term" : { "tag" : "wow" }},
            {"term" : { "tag" : "elasticsearch" }}
        ]
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

过滤不存在数据

"query": {
        "bool":{
            "filter":{
                "exists":{
                    "field":"subject" }
            }
        }   
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

统计某个字段出现的次数

size 0 不需要返回文档数据,只需要值

  "size": 0,
   "query": {
        "bool":{
            "filter":{
                "exists":{
                    "field":"proofreadresult" }
            }
        }   
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

返回 某个字段 ischeck值为false 的数量

"size": 0,
   "query": {
        "bool":{
            "must": [{"match": {"ischeck": "false"}}],
        }   
    }
}

"size": 0,
   "query": {
        "bool":{
            "must":  {"term" : { "ischeck" : "false" }}
        }   
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

返回的数据 value 就是我们需要的数据

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

2、字段过滤
过滤字段不存在的数据,filter + exists

使用 exists 进行过滤掉字段不存在的数据

 "size": 0, 
 "query": {
        "bool":{
            "filter":{"exists":{"field":"subject" }},
             "must": [{"range": {"createtime": {
                      "gte": 1654012800000,
                      "lte": 1655308799000}}
                     }]
         }   
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3、聚合查询
1)分组 https://blog.csdn.net/cainiao1412/article/details/120876972
聚合分组查询,使用terms,按照某个字段中的值来分类,通过size的值来确定返回文档的数量,如果不指定值,默认返回10个
Es query 中,使用 term 进行精准查询,不会对字段进行分词
使用terms,进行多个条件查询,类似 in

使用 script 进行多个字段 分组的实现,通过需要自己进行split处理

对uid进行分组

 "aggs": {
        "result": {
            "terms": {
                "field": "uid",
                "size": 2147483647
            } 
        }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

对 uid+subject 进行分组 通过 size 指定大小

"aggs": {
        "result": {
            "terms": {
                "script": { "inline": "doc['uid'].value +'-'+ doc['subject'].value"},
                "size": 40
            }
        }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2)聚合查询先进行过滤,然后分组

size 表示query返回的数据

subject 存在的数据中 按照 uid-subject 分组数据

  "size": 0,
  "aggs": {
    "filer-subject" : {
      "filter": {
        "bool" : {
          "filter" : [
            {"exists":{"field":"subject"}}
          ]
        }
      },
      "aggs": {
        "result" : {
            "terms": {
                "script": { "inline": "doc['uid'].value +'-'+ doc['subject'].value"},
                "size": 40
            } 
        }
      }
    }
  }
``

  # 返回的数据
  

```bash
 "aggregations" : {
    "filer-subject" : {
      "doc_count" : 3557,
      "result" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 988,
        "buckets" : [
          {
            "key" : "209372605317121-102",
            "doc_count" : 794
          },
          {
            "key" : "222580707950593-302",
            "doc_count" : 447
          },
          {
            "key" : "212246483697665-102",
            "doc_count" : 374
          },
          {
            "key" : "207843605348353-102",
            "doc_count" : 328
          }]
}}
  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

对应的java代码

Script script = new Script(ScriptType.INLINE,Script.DEFAULT_SCRIPT_LANG , "doc['uid'].value+'-'+doc['subject'].value", new HashMap<>());
        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("result").script(script).size(ESCommonConstant.ES_GROUP_QUERY_SIZE);
        // search
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.aggregation(aggregationBuilder);
        // query
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        List<QueryBuilder> must = boolQueryBuilder.must();

        if(Objects.nonNull(requestDWDProofreadRecordDTO.getStartTime()) && Objects.nonNull(requestDWDProofreadRecordDTO.getEndTime())){
             must.add(QueryBuilders.rangeQuery(ProofreadDetailConstant.CREATETIME).from(requestDWDProofreadRecordDTO.getStartTime()).to(requestDWDProofreadRecordDTO.getEndTime()));
        }
        must.add(QueryBuilders.boolQuery().must((QueryBuilders.existsQuery("subject"))));

        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.size(0);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

3)聚合多条件查询,并按指定的文档返回想要的数据

"size": 0,
  "aggs": {
  # 该数据是  条件 ischeck 值为true,subject 存在,
  # 分组 combinequestiontype分组返回总数量
    "ischeck-count" : {
      "filter": {
        "bool" : {
          "filter" : [
            {"exists":{"field":"subject"}} 
          ],
          "must" : {"term" : {"ischeck" : "true"} }  
        } 
      },
      "aggs": {
        "result" : {
            "terms": {
                "field": "combinequestiontype",
                "size": 30
            } 
        }
        
      }
    },

  # 该数据是 条件 proofreadresult存在,
  # 分组 combinequestiontype分组返回总数
  "proofreadresult-count" : {
      "filter": {
        "bool" : {
          "filter" : [
            {"exists":{"field":"proofreadresult"}} 
          ] 
        } 
      },
      "aggs": {
        "result" : {
            "terms": {
                "field": "combinequestiontype",
                "size": 30
            } 
        }
        
      }
    },
    

  # 该数据是 返回 isCheck 的数量
  "ischeck_total": {
        "terms": {
          "field": "ischeck"
        }
     },
 
   # 该数据是 返回 proofreadresult 字段存在 的数量
   # 即就是 proofreadresult  不为空的数量
 "proofreadresult_total": {
        "filter": {
              "bool" : {
                "filter" : [
                    {"exists":{"field":"proofreadresult"}} 
                  ] 
              } 
        }
     }
  }
  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

对应的java代码

// ischeck-count
        FilterAggregationBuilder ischeckCount = AggregationBuilders.filter("ischeck-count", QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("ischeck", true))
                .must(QueryBuilders.termQuery("uid", uid))
                .filter(QueryBuilders.existsQuery("xxx")))
                .subAggregation(AggregationBuilders.terms("result").field("xxx").size(30));

        // proofreadresult-count
        FilterAggregationBuilder proofreadCount = AggregationBuilders.filter("ischeck-count", QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("ischeck", true))
                .must(QueryBuilders.termQuery("uid", uid))
                .filter(QueryBuilders.existsQuery("xxx")));

        searchSourceBuilder.aggregation(ischeckCount);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

// 结果处理
List list = new ArrayList<>();
SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
Terms oneTerm = (Terms) response.getAggregations().asMap().get(“result”);
for (Terms.Bucket bucket : oneTerm.getBuckets()) {
ProofreadDetailDTO proofreadDetailDTO = new ProofreadDetailDTO();
// 此处自己split分隔处理
String[] strings = bucket.getKey().toString().split(“-”);
proofreadDetailDTO.setUid(Long.parseLong(strings[0]));
proofreadDetailDTO.setSubject(Integer.parseInt(strings[1]));
list.add(proofreadDetailDTO);
}

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

闽ICP备14008679号