springboot es 嵌套类型查询例子 es版本6.8.9

pom文件中新增

 
            org.elasticsearch.client
            elasticsearch-rest-high-level-client
            6.8.9
            
                
                    org.elasticsearch
                    elasticsearch
                
            
        
        
            org.elasticsearch
            elasticsearch
            6.8.9
        

索引结构:

{
    "student":{
        "type":"nested",
        "name":{
            "type":"keyword"
        },
        "hobby":{
            "type":"nested",
            "name":{
                "type":"keyword"
            }
        }
    },
    "teacher":{
        "type":"nested",
         "name":{
            "type":"keyword"
        },
        "class":{
            "type":"nested",
            "name":{
                "type":"keyword"
            }
        }
    }
}

1、嵌套精确查询,特别注意 嵌套查询的时候 查询的字段需要找到上层的字段,例如下面的 查询student 字段下的hobby 字段属的 name字段 在nestedQuery后面必须写 student.hobby 不能只写student。

还要注意 termQuery 是精确查询,新建索引的时候字段的类型会有影响到查询,keyword 类型可以直接通过termQuery 查询出来,其他的可能需要分词器,或者是matchQuery模糊查询

SearchRequest request = new SearchRequest("index_name"); // 初始化需要查询的索引

//查询student 字段下的hobby字段下的name字段的值 等于篮球的学生,这里特别注意第一层必须是你查询的字段的前一层字段
 QueryBuilder one= QueryBuilders.nestedQuery("student.hobby", QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("student.hobby.name","篮球")), ScoreMode.Total);

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // 初始化 最后组合成的条件
queryBuilder.must(one);
//初始化条件builer
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//加入组合成的条件到builder
        searchSourceBuilder.query(queryBuilder);
//设置查询的分页 第一个从0开始
        searchSourceBuilder.from(0);
//每页的大小为2
        searchSourceBuilder.size(2);
//初始化索引中加入 builder
 request.source(searchSourceBuilder);

try {
            SearchResponse searchResponse =restHighLevelClient.search(request, RequestOptions.DEFAULT);
            SearchHit[] hits = searchResponse.getHits().getHits();
//这里把数据转成实体
            List res = new ArrayList<>();
            for (SearchHit hit : hits) {
                res.add(JSON.parseObject(hit.getSourceAsString(), ExcelMarkModel.class));
            }
            System.out.println(JSON.toJSONString(res));
        }catch (Exception e){
            e.printStackTrace();
        }

2、嵌套查询中组合条件, 例如 满足上面的条件还必须满足 teacher字段下 class字段下 name的值为 体育。

 

 

SearchRequest request = new SearchRequest("index_name"); // 初始化需要查询的索引

//查询student 字段下的hobby字段下的name字段的值 等于篮球的学生,这里特别注意第一层必须是你查询的字段的前一层字段
 QueryBuilder one= QueryBuilders.nestedQuery("student.hobby", QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("student.hobby.name","篮球")), ScoreMode.Total);
//查询teacher字段下的class字段下的name字段的值 等于体育的老师,这里特别注意第一层必须是你查询的字段的前一层字段
 QueryBuilder two= QueryBuilders.nestedQuery("teacher.class", QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("teacher.class.name","体育")), ScoreMode.Total);

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // 初始化 最后组合成的条件
queryBuilder.must(one);
queryBuilder.must(two);
//初始化条件builer
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//加入组合成的条件到builder
        searchSourceBuilder.query(queryBuilder);
//设置查询的分页 第一个从0开始
        searchSourceBuilder.from(0);
//每页的大小为2
        searchSourceBuilder.size(2);
//初始化索引中加入 builder
 request.source(searchSourceBuilder);

try {
            SearchResponse searchResponse =restHighLevelClient.search(request, RequestOptions.DEFAULT);
            SearchHit[] hits = searchResponse.getHits().getHits();
//这里把数据转成实体
            List res = new ArrayList<>();
            for (SearchHit hit : hits) {
                res.add(JSON.parseObject(hit.getSourceAsString(), ExcelMarkModel.class));
            }
            System.out.println(JSON.toJSONString(res));
        }catch (Exception e){
            e.printStackTrace();
        }

 3、或者查询 第一个条件 满足篮球,现在或者满足羽毛球 也要查询出来

SearchRequest request = new SearchRequest("index_name"); // 初始化需要查询的索引

//查询student 字段下的hobby字段下的name字段的值 等于篮球和羽毛球的学生,这里特别注意第一层必须是你查询的字段的前一层字段
 QueryBuilder one= QueryBuilders.nestedQuery("student.hobby", QueryBuilders.boolQuery()
                .should(QueryBuilders.termQuery("student.hobby.name","篮球"))
                .should(QueryBuilders.termQuery("student.hobby.name","羽毛球")), ScoreMode.Total);
//查询teacher字段下的class字段下的name字段的值 等于体育的老师,这里特别注意第一层必须是你查询的字段的前一层字段
 QueryBuilder two= QueryBuilders.nestedQuery("teacher.class", QueryBuilders.boolQuery()
                .must(QueryBuilders.termQuery("teacher.class.name","体育")), ScoreMode.Total);

BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // 初始化 最后组合成的条件
queryBuilder.must(one);
queryBuilder.must(two);
//初始化条件builer
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//加入组合成的条件到builder
        searchSourceBuilder.query(queryBuilder);
//设置查询的分页 第一个从0开始
        searchSourceBuilder.from(0);
//每页的大小为2
        searchSourceBuilder.size(2);
//初始化索引中加入 builder
 request.source(searchSourceBuilder);

try {
            SearchResponse searchResponse =restHighLevelClient.search(request, RequestOptions.DEFAULT);
            SearchHit[] hits = searchResponse.getHits().getHits();
//这里把数据转成实体
            List res = new ArrayList<>();
            for (SearchHit hit : hits) {
                res.add(JSON.parseObject(hit.getSourceAsString(), ExcelMarkModel.class));
            }
            System.out.println(JSON.toJSONString(res));
        }catch (Exception e){
            e.printStackTrace();
        }

 最后的说一下 模糊查询 就是把termQuery 改成matchQuery() ,还有特别注意中文分词

你可能感兴趣的:(java,spring,boot,es,elasticsearch)