RestHighLevelClient实现ElasticSearch关联查询之父子文档

RestHighLevelClient实现ElasticSearch关联查询之父子文档今天分享,承接上一篇内容:

DSL操作关联查询

这篇我们通过javaAPI的方式实现:

一、springboot 配置

1、pom文件引用:

      <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.9.3</version>
            <exclusions>
                <exclusion>
                    <groupId>org.elasticsearch</groupId>
                    <artifactId>elasticsearch</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.elasticsearch.client</groupId>
                    <artifactId>elasticsearch-rest-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.9.3</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.9.3</version>
        </dependency>

        <!-- elasticsearch 新版本官方sdk,版本号需与使用的es版本一致 -->
        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>7.17.0</version>
        </dependency>

2、初始化配置es操作类


import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient(){
 
        RestClientBuilder builder=RestClient.builder(
               // new HttpHost("116.204.80.158", 9200, "http"),
                new HttpHost("116.204.80.155", 9200, "http"));
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "123456"));
        builder.setHttpClientConfigCallback(f -> f.setDefaultCredentialsProvider(credentialsProvider));
        RestHighLevelClient client = new RestHighLevelClient( builder);
        return client;
    }
}

3、业务层引用

    @Qualifier("restHighLevelClient")
    @Autowired
    private RestHighLevelClient client;

    private static final String indexName = "test_nandao_index";

    private static final String tableName = "UserInfo";
    private static final String workTableName = "WorkInfo";
    private static final String schoolTableName = "SchoolInfo";
    private static final String UserWorkRelation = tableName+"_"+workTableName+"_relation";

二、核心伪代码

1、创建父子索引

@Override
    public boolean createIndex(String index) throws IOException {
        //创建json数

        XContentBuilder mapping = XContentFactory.jsonBuilder()
                .startObject()

                .startObject("properties")

                .startObject("content")
                .field("type","text")
                .endObject()

                .startObject("title")
                .field("type","text")
                .endObject()

                .startObject(tableName+"_"+workTableName+"_relation")
                .field("type","join")
                .startObject("relations")
               // .field("blog","comment")
                .field(tableName,workTableName)
                .endObject()
                .endObject()

                .endObject()

                .endObject();

        CreateIndexRequest request = new CreateIndexRequest(index)
                .settings(Settings.builder()
                        .put("number_of_shards", 2)
                        .put("number_of_replicas", 1)
                        .build())
                .mapping(mapping)
                ;

        //1.创建索引请求
      //  CreateIndexRequest request = new CreateIndexRequest(index);
        String string = request.aliases().toString();
        //2.客户端执行请求IndicesClient,请求后获得相应
        log.info("请求:{}", JSONObject.toJSONString(request));
        log.info("请求:{}",request.toString());
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        log.info("返回:{}", JSON.toJSONString(response));
        return response.isAcknowledged();
    }

kibana查看

GET /nandao_parent_sub_index/_mapping

2、判断索引是否存在

   @Override
    public boolean isExit(String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest(index);
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        return exists;
    }

3、删除索引

    @Override
    public boolean delete(String index) throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        return delete.isAcknowledged();
    }

4、添加父文档

 @Override
    public boolean addDocument(String index, String id, Object object) throws IOException {
        IndexRequest request = new IndexRequest(index);
        //规则 一般的文档形如 put /index/_doc/1
        //request.id(id);//如果不设置id的话会自动分配id
        request.timeout("1s");//设置超时时间
        System.out.println("JSON.toJSONString(object):"+ JSON.toJSONString(object));
        //将我们的数据放入请求Json中
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(object);
        //添加join关联索引
        JSONObject relationObject = new JSONObject();
       // relationObject.put(tableName,workTableName);
        relationObject.put("name",tableName);
        jsonObject.put(UserWorkRelation,relationObject);
        request.source(JSON.toJSONString(jsonObject), XContentType.JSON);
        log.info("请求:{}", JSONObject.toJSONString(request));
        log.info("请求1:{}", JSON.toJSONString(request));
        log.info("请求2:{}", JSON.toJSONString(jsonObject));
        //客户端发送请求,获取相应的结果
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        return response.getShardInfo().getSuccessful()>0?true:false;
    }

5、更新父文档

    @Override
    public boolean updateDocument(UserInfoVo user, String index, String id) throws IOException {
        UpdateRequest request = new UpdateRequest(index, id);
        request.timeout("1s");

        //将我们的数据放入请求Json中
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(user);
        //添加join关联索引
        JSONObject relationObject = new JSONObject();
        // relationObject.put(tableName,workTableName);
        relationObject.put("name",tableName);
        jsonObject.put(UserWorkRelation,relationObject);

        request.doc(JSON.toJSONString(jsonObject), XContentType.JSON);
        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
        return update.getShardInfo().getSuccessful()>0?true:false;
    }

6、添加子文档

    @Override
    public boolean addDocumentSub(String index, String parentId, Object object) throws IOException {
        IndexRequest request = new IndexRequest(index).routing(parentId);//设置索引和路由
        //规则 一般的文档形如 put /index/_doc/1
        //request.id(id);//如果不设置id的话会自动分配id
        request.timeout("1s");//设置超时时间
        System.out.println("JSON.toJSONString(object):"+ JSON.toJSONString(object));
        //将我们的数据放入请求Json中
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(object);
        //添加join关联索引
        JSONObject relationObject = new JSONObject();
        relationObject.put("name",workTableName);
        relationObject.put("parent",parentId);
        jsonObject.put(UserWorkRelation,relationObject);
        request.source(JSON.toJSONString(jsonObject), XContentType.JSON);
        log.info("请求:{}", JSONObject.toJSONString(request));
        log.info("请求1:{}", JSON.toJSONString(request));
        log.info("请求2:{}", JSON.toJSONString(jsonObject));
        //客户端发送请求,获取相应的结果
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        return response.getShardInfo().getSuccessful()>0?true:false;
    }

创建普通文档  

    @Override
    public boolean createDocument(String index, Object object) throws IOException {
        IndexRequest request = new IndexRequest(index);
        //规则 一般的文档形如 put /index/_doc/1
       // request.id(id);//如果不设置id的话会自动分配id
        request.timeout("1s");//设置超时时间
        System.out.println("JSON.toJSONString(object):"+ JSON.toJSONString(object));
        //将我们的数据放入请求Json中
        request.source(JSON.toJSONString(object), XContentType.JSON);
        //客户端发送请求,获取相应的结果
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        return response.getShardInfo().getSuccessful()>0?true:false;
    }

      7、判断是否是doc格式

    @Override
    public boolean isdocuexit(String index, String id) throws IOException {
        GetRequest getRequest = new GetRequest(index,id);
        //不获取返回的_source上下文
        getRequest.fetchSourceContext(new FetchSourceContext(false));
        getRequest.storedFields("_none_");
        return client.exists(getRequest, RequestOptions.DEFAULT);
    }

8、根据id和索引查询

    @Override
    public String getDoucumment(String index, String id) throws IOException {
        GetRequest getRequest = new GetRequest(index, id);
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
        return response.getSourceAsString();
    }

9、根据父id查询

    @Override
    public String getDoucummentByParentId(String index, TreeMap<String, Object> content,String parentId) throws IOException {
         
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
      
        ParentIdQueryBuilder build = JoinQueryBuilders.parentId("WorkInfo",parentId);
        sourceBuilder.query(build);
        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);
        System.out.println("dsl===1==="+sourceBuilder.toString());

        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();

       // SearchRequest searchRequest = new SearchRequest(index);
        searchResponse.getHits().forEach(hi ->{
            log.info("查询结果:{}",hi.getSourceAsString());
        });
        return hits.toString();
    }

对应DSL语句

POST /nandao_parent_sub_index/_search 
{
	"query": {
		"parent_id": {
			"type": "WorkInfo",
			"id": "tYTxYoUBJlO7GBNmNPml"
		}
	}
}

 

10、Has Child 查询,返回父文档

    @Override
    public String getDoucummentHasChild(String userName, String index) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        HasChildQueryBuilder build = JoinQueryBuilders.hasChildQuery("WorkInfo",QueryBuilders.matchQuery("userName", "Jack"), ScoreMode.None);
        sourceBuilder.query(build);
        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);
        System.out.println("dsl===1==="+sourceBuilder.toString());
        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        searchResponse.getHits().forEach(hi ->{
            log.info("查询结果:{}",hi.getSourceAsString());
        });
        return hits.toString();
    }

对应DSL语句:

POST /nandao_parent_sub_index/_search
{
	"query": {
		"has_child": {
			"type": "WorkInfo",
			"query": {
				"match": {
					"userName": "Jack"
				}
			}
		}
	}
}

 11、Has parent 查询,返回子文档

    @Override
    public String getDoucummentHasParent(String userName, String index) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        HasParentQueryBuilder build= JoinQueryBuilders.hasParentQuery("UserInfo", QueryBuilders.matchQuery("userName", "wangwu"), false);
        sourceBuilder.query(build);
        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);
        System.out.println("dsl===1==="+sourceBuilder.toString());
        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        searchResponse.getHits().forEach(hi ->{
            log.info("查询结果:{}",hi.getSourceAsString());
        });
        return hits.toString();
    }

对应DSL语句:

GET /nandao_parent_sub_index/_search
{
  "query": {
    "has_parent": {
      "parent_type": "UserInfo",
      "query": {
        "match": {
          "userName": "wangwu"
        }
      }
    }
  }
}

 12、通过索引查

   @Override
    public String getAllDoucummentByIndex(String index) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        return hits.toString();
    }

13、通过索引和id删除文档

   @Override
    public boolean deleteDocument(String index, String id) throws IOException {
        DeleteRequest request = new DeleteRequest(index,id);
        request.timeout("1s");
        DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT);
        return deleteResponse.getShardInfo().getSuccessful()>0?true:false;
    }

14、批量添加文档

    @Override
    public boolean addmoredocument(List<Object> list, String index, String id) throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("1s");
        //批量处理请求
        for (int i=0;i<list.size();i++){
            bulkRequest.add(
                    new IndexRequest(index)
                            //.id(id)
                            .source(JSON.toJSONString(list.get(i)), XContentType.JSON));
        }
        BulkResponse responses = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        //是否失败 false-没有失败
        return responses.hasFailures()?false:true;
    }

15、termQuery

    @Override
    public List<Map<String, Object>> termQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        //构建查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        System.out.println(content.firstKey());
        //查询条件
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(content.firstKey(),content.get(content.firstKey()));
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //获取多少条数据
        sourceBuilder.size(size);
        //从第几行开始
        sourceBuilder.from(from);
        //是否要将查询的结果中将搜索的关键词高亮
        if (ishigh){
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            //设置高亮的属性
            highlightBuilder.field(content.firstKey());
            //也可以自定义高亮的样式,这里我使用的是默认的方式
            sourceBuilder.highlighter(highlightBuilder);
        }
        System.out.println("dsl===1==="+sourceBuilder.toString());
        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);
        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();

        ArrayList<Map<String, Object>> result = new ArrayList<>();
        for (SearchHit searchHit:hits){
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            //获取高亮的信息
            HighlightField property = highlightFields.get(content.firstKey());
            //查询的元素数据(没有高亮)
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            if (ishigh){
                if (property!=null){
                    Text[] fragments = property.fragments();
                    String n_title = "";
                    for (Text text:fragments){
                        n_title += text;
                    }
                    sourceAsMap.put(content.firstKey(),n_title);
                }
            }
            result.add(sourceAsMap);
        }
        System.out.println("result==1===:"+result);
        return result;
    }

16、matchQuery

@Override
    public List<Map<String, Object>> matchQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        //构建查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(content.firstKey(),content.get(content.firstKey()));

        sourceBuilder.query(matchQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //获取多少条数据
        sourceBuilder.size(size);
        //从第几行开始
        sourceBuilder.from(from);
        //是否要高亮
        if (ishigh){
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            //设置高亮的属性
            highlightBuilder.field(content.firstKey());
            //也可以自定义高亮的样式,这里我使用的是默认的方式
            sourceBuilder.highlighter(highlightBuilder);
        }

        System.out.println("dsl===2==="+sourceBuilder.toString());

        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);
        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();

        ArrayList<Map<String, Object>> result = new ArrayList<>();
        for (SearchHit searchHit:hits){
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            //获取高亮的信息
            HighlightField property = highlightFields.get(content.firstKey());
            //查询的元素数据(没有高亮)
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            System.out.println("sourceAsMap===2==="+sourceAsMap);
            if (ishigh){
                if (property!=null){
                    Text[] fragments = property.fragments();
                    String n_title = "";
                    for (Text text:fragments){
                        n_title += text;
                    }
                    sourceAsMap.put(content.firstKey(),n_title);
                }
            }
            result.add(sourceAsMap);
        }
        System.out.println("result==2===:"+result);

        return result;
    }

17、boolmustQuery

@Override
    public List<Map<String, Object>> boolmustQuery(String index, TreeMap<String, Object> content, int size, int from, boolean ishigh) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        //构建查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        Set keys = content.keySet();
        for (Object key:keys){
            //将要查询的条件加入
            boolQueryBuilder.must(QueryBuilders.termQuery((String) key,content.get(key)));
        }
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //获取多少条数据
        sourceBuilder.size(size);
        //从第几行开始
        sourceBuilder.from(from);

        System.out.println("dsl===3==="+sourceBuilder.toString());
        //将查询条件放入需要查询中
        searchRequest.source(sourceBuilder);
        //获取相应的数据
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();
        ArrayList<Map<String, Object>> result = new ArrayList<>();
        for (SearchHit searchHit:hits){
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            //获取高亮的信息
            HighlightField property = highlightFields.get(content.firstKey());
            //查询的元素数据(没有高亮)
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            System.out.println("sourceAsMap===2==="+sourceAsMap);
            if (ishigh){
                if (property!=null){
                    Text[] fragments = property.fragments();
                    String n_title = "";
                    for (Text text:fragments){
                        n_title += text;
                    }
                    sourceAsMap.put(content.firstKey(),n_title);
                }
            }
            result.add(sourceAsMap);
        }

        System.out.println("result==3===:"+result);
        return result;
    }

到此关联关系处理基本分享完毕,同时也可以参考这篇文章:

es父子查询处理

下篇我们分析es的理论与架构组成敬请期待!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值