当前位置:   article > 正文

Elasticsearch嵌套查询must和mustNot_elasticsearch must

elasticsearch must

场景:在bug关联固件的时候将bug的数据放到固件的数据下,可以根据固件数据下是否包含bug数据查询出已关联和未关联的数据。

ES文档结构

目录

1.must查询此bug关联的固件

java代码

2.mustNot查询此bug未关联的固件

java代码

3.劫后余生       

4.闲来无事must_not跟must下的多条件关系不一样

4.1 es查询

4.2 java代码



1.must查询此bug关联的固件

  1. {
  2. "query":{
  3. "nested":{
  4. "path":"s25_kernel_check",
  5. "query":{
  6. "bool":{
  7. "must":[
  8. {
  9. "match":{
  10. "s25_kernel_check.cve_id":"value"
  11. }
  12. },
  13. {
  14. "match":{
  15. "s25_kernel_check.exploit-db":"value"
  16. }
  17. }
  18. ]
  19. }
  20. }
  21. }
  22. }
  23. }

同时满足must下的条件才可以被返回

java代码

  1. BoolQueryBuilder must = QueryBuilders.boolQuery();
  2. if (cvesById.getCveId()!=null){
  3. must.must(QueryBuilders.matchQuery("s25_kernel_check.cve_id", cvesById.getCveId()));
  4. }
  5. if (cvesById.getExploitDb()!=null){
  6. must.must(QueryBuilders.matchQuery("s25_kernel_check.exploit-db", cvesById.getExploitDb()));
  7. }
  8. HashMap<String, Object> map2 = new HashMap<>();
  9. NestedQueryBuilder s25_kernel_check = QueryBuilders.nestedQuery("s25_kernel_check", must,ScoreMode.Max);
  10. SearchQuery queryBuilder = new NativeSearchQueryBuilder()
  11. .withQuery(s25_kernel_check)
  12. .withFields("firmware_id")
  13. .build();
  14. AggregatedPage<Cvesdd> page = template.queryForPage(queryBuilder, Cvesdd.class, new SearchResultMapper() {
  15. @Override
  16. public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
  17. map2.put("total", searchResponse.getHits().totalHits);
  18. List<T> list = new ArrayList<>();
  19. return new AggregatedPageImpl<T>(list);
  20. }
  21. });
  22. Integer total= new Integer(String.valueOf((Long) map2.get("total")));
  23. if (total == 0){
  24. total = 10;
  25. }
  26. NestedQueryBuilder new_s25_kernel_check = QueryBuilders.nestedQuery("s25_kernel_check", must,ScoreMode.Max);
  27. SearchQuery new_queryBuilder = new NativeSearchQueryBuilder()
  28. .withQuery(new_s25_kernel_check)
  29. .withFields("firmware_id")
  30. .withPageable(PageRequest.of(0,total))
  31. .build();
  32. List<Cvesdd> list = template.queryForList(new_queryBuilder, Cvesdd.class);

2.mustNot查询此bug未关联的固件

  1. {
  2. "size": 200,
  3. "query": {
  4. "bool": {
  5. "must_not": [
  6. {
  7. "nested": {
  8. "path": "s25_kernel_check",
  9. "query": {
  10. "bool": {
  11. "must": [
  12. {
  13. "match": {
  14. "s25_kernel_check.cve_id": "value"
  15. }
  16. },
  17. {
  18. "match": {
  19. "s25_kernel_check.exploit-db": "value"
  20. }
  21. }
  22. ]
  23. }
  24. }
  25. }
  26. }
  27. ]
  28. }
  29. }
  30. }

排除同时满足must下条件的数据并返回

java代码

  1. HashMap<String, Object> totalMap = new HashMap<>();
  2. BoolQueryBuilder must = QueryBuilders.boolQuery();
  3. if (cvesById.getCveId()!=null){
  4. must.must(QueryBuilders.matchQuery("s25_kernel_check.cve_id", cvesById.getCveId()));
  5. }
  6. if (cvesById.getExploitDb()!=null){
  7. must.must(QueryBuilders.matchQuery("s25_kernel_check.exploit-db", cvesById.getExploitDb()));
  8. }
  9. NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("s25_kernel_check", must,ScoreMode.Max);
  10. BoolQueryBuilder newBool = QueryBuilders.boolQuery();
  11. newBool.mustNot(nestedQuery);
  12. SearchQuery queryBuilder = new NativeSearchQueryBuilder()
  13. .withQuery(newBool)
  14. .withFields("firmware_id")
  15. .build();
  16. AggregatedPage<Cvesdd> page = template.queryForPage(queryBuilder, Cvesdd.class, new SearchResultMapper() {
  17. @Override
  18. public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
  19. totalMap.put("total", searchResponse.getHits().totalHits);
  20. List<T> list = new ArrayList<>();
  21. return new AggregatedPageImpl<T>(list);
  22. }
  23. });
  24. Integer total= new Integer(String.valueOf((Long) totalMap.get("total")));
  25. SearchQuery new_queryBuilder = new NativeSearchQueryBuilder()
  26. .withQuery(newBool)
  27. .withFields("firmware_id")
  28. .withPageable(PageRequest.of(0,total))
  29. .build();
  30. List<Cvesdd> list = template.queryForList(new_queryBuilder, Cvesdd.class);

查询语句跟代码的对应关系


3.劫后余生       

        OK,上面是满足了我想要的效果,但是发现在关联后,在es中再增加一条不同任务但是固件已经被某条bug关联过的数据,就会发现某条bug的未关联固件和已关联固件都会出现这个固件,原因是es中其实是存放的任务跟固件的关联关系,又因为业务关系,会存在多条相同固件但是不同任务的数据,关联之后创建的新任务已有固件数据,其中并未包含某条bug的数据,所以才会导致这样,那么ok,在查询未关联的逻辑之前,先查询一下已经关联的数据,不管它在哪个任务,只要所有的固件数据,有一条满足包含此条bug数据,那么我们就认为此条固件已经关联了这个bug了

4.闲来无事must_not跟must下的多条件关系不一样

        还尝试了排除嵌套查询满足或者id存在集合中的数据,gpt说这俩是and的关系,但是怎么测都是or的关系,现在es有三条id等于137的数据,其中有两条是满足嵌套查询的条件,如果是and那么应该是给我返回只是id等于137不满足嵌套查询的数据,但是并没有。。

        但是如果将must_not改成must下面的这个两个就成了and的关系,就会返回同时满足这两个条件的数据

        就很奇怪!离谱它妈给离谱开门,离谱到家了~

        那么我们来看看gpt对疑问的回答

4.1 es查询

  1. {
  2. "size": 200,
  3. "query": {
  4. "bool": {
  5. "must_not": [
  6. {
  7. "terms": {
  8. "firmware_id": [
  9. 137
  10. ]
  11. }
  12. },
  13. {
  14. "nested": {
  15. "path": "s25_kernel_check",
  16. "query": {
  17. "bool": {
  18. "must": [
  19. {
  20. "match": {
  21. "s25_kernel_check.cve_id": "CVE-2010-3848,CVE-2010-3850,CVE-2010-4073"
  22. }
  23. },
  24. {
  25. "match": {
  26. "s25_kernel_check.exploit-db": "17787"
  27. }
  28. }
  29. ]
  30. }
  31. }
  32. }
  33. }
  34. ]
  35. }
  36. }
  37. }

4.2 java代码


 最上面所提到的关联操作

  1. //查询es中要关联的固件数据
  2. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
  3. boolQuery.must(QueryBuilders.matchQuery("firmware_id",ids[i]));
  4. SearchQuery searchQuery = new NativeSearchQueryBuilder()
  5. .withQuery(boolQuery)
  6. //指定索引
  7. .withIndices("information_result")
  8. //指定type
  9. .withTypes("fulldata")
  10. .build();
  11. List<?> results = template.query(searchQuery, response -> {
  12. List<Object> list = new ArrayList<>();
  13. for (SearchHit hit : response.getHits()) {
  14. Map<String, Object> sourceAsMap = hit.getSourceAsMap();
  15. sourceAsMap.put("id",hit.getId());
  16. list.add(sourceAsMap);
  17. }
  18. return list;
  19. });
  20. //构建批量插入的集合
  21. List<IndexQuery> queries = new ArrayList<>();
  22. for (int i1 = 0; i1 < results.size(); i1++) {
  23. Map oldData = (HashMap) results.get(i1);
  24. ArrayList s25_kernel_check1 =new ArrayList();
  25. boolean key1 = oldData.containsKey("s25_kernel_check");
  26. if (key1){
  27. s25_kernel_check1 = (ArrayList) oldData.get("s25_kernel_check");
  28. }
  29. //添加的bug信息
  30. HashMap<String, Object> stringObjectHashMap = new HashMap<>();
  31. //.....添加本条新bug数据
  32. s25_kernel_check1.add(stringObjectHashMap);
  33. oldData.put("s25_kernel_check",s25_kernel_check1);
  34. //构建插入数据
  35. IndexQuery indexQuery = new IndexQuery();
  36. //指定id,覆盖原有数据
  37. indexQuery.setId(oldData.get("id").toString());
  38. oldData.remove("id");
  39. JSONObject newData=new JSONObject(oldData);
  40. //插入数据
  41. indexQuery.setSource(newData.toString());
  42. //索引
  43. indexQuery.setIndexName("information_result");
  44. //类型
  45. indexQuery.setType("fulldata");
  46. //3.添加到queries
  47. queries.add(indexQuery);
  48. }
  49. //4.添加数据
  50. template.bulkIndex(queries);
  51. queries.clear();

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

闽ICP备14008679号