版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/paditang/article/details/78970445</a>

前言

官方推荐的RestHighLevelClient在网络上相关文档较少,因此很多坑都需要通过自己看官方文档,源代码解决。因此这系列文章就是为了解决这些文档提及不全的部分,如果有文章没提到的部分,欢迎一起交流。

这篇就关于使用RestClient操作索引,内容就是解决问题的实例。同样,一切版本以5.6.0为准。其他升级版本新的api不属此列。

正文

问题根源

​ 由于使用RestHighLevelClient(后称为rhlClient)时,进行Index操作,所有IndexRequest都会校验Index,type,source,contentType不为空。

 // 校验源码
if (type == null) {
            validationException = addValidationError("type is missing", validationException);
        }
        if (source == null) {
            validationException = addValidationError("source is missing", validationException);
        }
        if (contentType == null) {
            validationException = addValidationError("content type is missing", validationException);
        }

​ 所以,如果只创建索引时一定会遇到校验抛出异常,而是否有其他方法绕过校验不得而知,而本人的方法是使用老版本RestClient直接操作。虽然在封装上会比rhlClient简陋,但是同时具备了更高的灵活性。

操作实例

  1. 创建索引

    首先给出rest api 操作的格式:

    因为整合了ik中文分词器,所以“analyzer”: “ik_max_word”此处参考安装配置ik分词器

    /PUT {{host}}:{{port}}/demo
    {
    "mappings":{
        "doc":{
            "properties":{
                "title":{
                    "type":"text",
                     "analyzer": "ik_max_word"
                },
                "content":{
                    "type":"text",
                     "analyzer": "ik_max_word"
                },
                "uniqueId":{
                    "type":"keyword",
                    "index":"not_analyzed"
                },
                "created":  {
                    "type":   "date", 
                    "format": "strict_date_optional_time||epoch_millis"
                }
            }
        }
    },
    "settings":{
            "number_of_shards":3,
            "number_of_replicas":1
    }
    }
    @Test
    public void indexTest() {
        try {
                // 借助indexRequest的json拼接工具
            IndexRequest indexRequest = new IndexRequest();
            XContentBuilder builder = JsonXContent.contentBuilder()
                    .startObject()
                        .startObject("mappings")
                            .startObject("doc")
                                .startObject("properties")
                                    .startObject("title")
                                        .field("type","text")
                                        .field("analyzer","ik_max_word")
                                    .endObject()
                                    .startObject("content")
                                        .field("type","text")
                                        .field("index","analyzed")
                                        .field("analyzer","ik_max_word")
                                    .endObject()
                                    .startObject("uniqueId")
                                        .field("type","keyword")
                                        .field("index","not_analyzed")
                                    .endObject()
                                    .startObject("created")
                                        .field("type","date")
                                        .field("format","strict_date_optional_time||epoch_millis")
                                    .endObject()
                                .endObject()
                            .endObject()
                        .endObject()
                        .startObject("settings")
                            .field("number_of_shards",3)
                            .field("number_of_replicas",1)
                        .endObject()
                    .endObject();
            indexRequest.source(builder);
                // 生成json字符串
            String source = indexRequest.source().utf8ToString();
            HttpEntity entity = new NStringEntity(source, ContentType.APPLICATION_JSON);
           // 使用RestClient进行操作 而非rhlClient
                Response response = client.performRequest("put", "/demo", Collections.<String, String> emptyMap(),
                    entity);
            System.out.println(response);
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    
    }
    // 结果
    /GET {{host}}:{{port}}/demo
    {
       "demo": {
           "aliases": {},
           "mappings": {
               "doc": {
                   "properties": {
                       "content": {
                           "type": "text",
                           "analyzer": "ik_max_word"
                       },
                       "created": {
                           "type": "date"
                       },
                       "title": {
                           "type": "text",
                           "analyzer": "ik_max_word"
                       },
                       "uniqueId": {
                           "type": "keyword"
                       }
                   }
               }
           },
           "settings": {
               "index": {
                   "creation_date": "1515043588766",
                   "number_of_shards": "3",
                   "number_of_replicas": "1",
                   "uuid": "8a7GoGgwQFyr8s3Ehs8HSA",
                   "version": {
                       "created": "5060099"
                   },
                   "provided_name": "demo"
               }
           }
       }
    }

    可以看到映射和设置已完成配置。

    如果有其他需要的配置,可以参考官网api,然后只要拼接对应的json字符串,使用RestClient请求即可。

  2. 创建类型映射

    首先必须保证索引存在,才能创建类型映射。

    /POST {{host}}:{{port}}/newspaper/sports/_mapping
    {
    "properties":{
        "content":{
            "type":"text",
            "analyzer":"ik_max_word",
            "index":"analyzed"
        }
    }
    }
    @Test
    public void indexTest2() {
        try {
            IndexRequest indexRequest = new IndexRequest();
            XContentBuilder builder = JsonXContent.contentBuilder()
                    .startObject()
                        .startObject("properties")
                            .startObject("content")
                                .field("type","text")
                                .field("analyzer","ik_max_word")
                                .field("index","analyzed")
                            .endObject()
                        .endObject()
                    .endObject();
            indexRequest.source(builder);
            String source = indexRequest.source().utf8ToString();
            HttpEntity entity = new NStringEntity(source, ContentType.APPLICATION_JSON);
            Response response = client.performRequest("post", "/newspaper/sports/_mapping", Collections.<String, String> emptyMap(),
                    entity);
            System.out.println(response);
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
    /GET {{host}}:{{port}}/newspaper
    {
       "newspaper": {
           "aliases": {},
           "mappings": {
               "sports": {
                   "properties": {
                       "content": {
                           "type": "text",
                           "analyzer": "ik_max_word"
                       }
                   }
               }
           },
           "settings": {
               "index": {
                   "creation_date": "1515045134942",
                   "number_of_shards": "5",
                   "number_of_replicas": "1",
                   "uuid": "HZ7b3ey1TNu2erzTtG-1Fg",
                   "version": {
                       "created": "5060099"
                   },
                   "provided_name": "newspaper"
               }
           }
       }
    }

    创建sports类型映射成功。主要点还是在于拼接json字符串。

  3. 查看索引是否存在

    public boolean checkIndexExist(String index) throws IOException {
        Response response = restClient.performRequest("HEAD", index);
        boolean exist = response.getStatusLine().getReasonPhrase().equals("OK");
        return exist;
    }
  4. 删除索引

    /DELETE {{host}}:{{port}}/newspaper/
    • 1
    Response response = restClient.performRequest("DELETE", indexName);
    • 1

总结

​ 以上便是对索引的大部分操作,可以看到绝大部分都是通过restClient绕过rhlClient的空类型检测。所以如果还有其他对索引的需求,也可以尝试使用IndexRequest的Json拼接工具,拼接好Json字符串后,使用restClient发出请求。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐