springboot整合es插入时ActionRequestValidationException: Validation Failed: 1: type is missing

简单记录一下

错误说明:此错误是发生在使用java RestHighLevelClient操作向ES中单挑/多条插入数据时报的错,关键报错信息

org.elasticsearch.action.ActionRequestValidationException: Validation Failed: 
1: type is missing;2: type is missing;

错误原因:安装的es和分词器版本太低,例如lz使用的是6.6.2版本的es,使用RestHighLevelClient插入时一直报错,换成7.3.2版本后一次性插入成功。
在一个索引中,你可以定义一个或多个类型,一个类型是你的索引的一个逻辑上的分类,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型,比如说,我们订单数据索引中我们把订单信息作为一个类型,订单相关的物流信息做为一个类型。但在6.0开始建议index只包含一个type,在7.0之后开始去除。
根据提示也可以知道大概是类型的错误,就是创建索引的类型字段问题,另外还需注意es与ik的版本统一问题,安装的es客户端与java api的版本统一问题,lz的代码如下

    public void createIndex() {
    
    
        CreateIndexRequest request = new CreateIndexRequest(indexName);//创建索引
//        request.settings(Settings.builder()
//                //分片参数
//                .put("index.number_of_shards", 5)
//                .put("index.number_of_replicas", 2)
//        );

        request.mapping("{\"properties\":{\"newsId\":{\"type\":\"text\",\"index\":false},\"newsTitle\":{\"type\":\"text\",\"index\":true,\"analyzer\":\"ik_smart\"},\"newsContont\":{\"type\":\"text\",\"index\":true,\"analyzer\":\"ik_smart\"},\"readCount\":{\"type\":\"integer\",\"index\":true}}}",//类型映射,需要的是一个JSON字符串
                XContentType.JSON);

        //为索引设置一个别名
        request.alias(
                new Alias("news_alias")
        );
        //可选参数
        //超时,等待所有节点被确认(使用TimeValue方式)
        request.setTimeout(TimeValue.timeValueSeconds(1000));
        //连接master节点的超时时间(使用TimeValue方式)
        request.setMasterTimeout(TimeValue.timeValueSeconds(1000));
        //在创建索引API返回响应之前等待的活动分片副本的数量,以int形式表示。
//        request.waitForActiveShards(ActiveShardCount.from(2));

        try {
    
    
            CreateIndexResponse createIndexResponse = client.indices().create(request, DEFAULT);

            if (createIndexResponse.isAcknowledged()) {
    
    
                System.out.println("所有节点都已确认请求" + createIndexResponse.index());
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

所以解决问题的方式有两种:
1、将上述代码中request.mapping("{\"properties\":{\"newsId\":{\"type\":\"text\",\"index\":false},\"newsTitle\":{\"type\":\"text\",\"index\":true,\"analyzer\":\"ik_smart\"},\"newsContont\":{\"type\":\"text\",\"index\":true,\"analyzer\":\"ik_smart\"},\"readCount\":{\"type\":\"integer\",\"index\":true}}}",//类型映射,需要的是一个JSON字符串 XContentType.JSON);中的json格式类型修改,修改成适合es6规范的数据,lz试了很多次都没有成功
2、重装es,将es修改为7.0以上的版本重新运行代码即可

注释说明:lz使用transportCient(此对象已过时,官方说将在7中声明过时,8中完全废除)创建和插入对象都是正常的在此贴一下代码:

package com.icoding.springbootesjdelasticsearch.core;


import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;

/**
 * 用于获取es的客户端链接对象
 *
 * @description:
 * @author: Czw
 * @create: 2020-06-26 15:28
 **/
public class TransportClientUtil {
    
    

    public static final String HOST = "127.0.0.1";

    //es通讯端口
    public static final int PORT = 9300;

    //es索引库名称(库名称)
    public static final String INDEX_NAME = "jdgoodsdb";
    //es类型表名称(表名)
    public static final String TABLE_NAME = "content";


    //获取es链接客户端
    public static TransportClient getTransportClientUtil() {
    
    
        try {
    
    
            //设置集群信息
            Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
            //创建transportClient对象
            TransportClient transportClient = new PreBuiltTransportClient(settings);
            //开始连接服务
            transportClient.addTransportAddress(new TransportAddress(InetAddress.getByName(HOST), PORT));
            return transportClient;
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return null;
    }

    //创建索引库
    public static void createIndexDB() {
    
    

        //获取es客户端,链接对象
        TransportClient transportClientUtil = getTransportClientUtil();
        //创建索引
        CreateIndexResponse createIndexResponse = transportClientUtil.admin().indices().prepareCreate(INDEX_NAME).get();
        System.out.println(createIndexResponse.isAcknowledged());
        //关闭连接
        transportClientUtil.close();
    }

    //创建索引规则
    public static void createIndexData() {
    
    
        TransportClient transportClient = null;
        try {
    
    
            transportClient = getTransportClientUtil();
            CreateIndexResponse createIndexResponse = transportClient.admin().indices().prepareCreate(INDEX_NAME).get();
            if (createIndexResponse.isAcknowledged()) {
    
    
                XContentBuilder xContentBuilder = XContentFactory.jsonBuilder().startObject()
                        .startObject(TABLE_NAME)
                        .startObject("properties")
                        .startObject("id").field("type", "long").field("store", true).endObject()
                        .startObject("cid").field("type", "text").field("store", true).endObject()
                        //使用ik分词器有两种: ik_smart最小切分,ik_ max word最细切分,有个前提:你es服务必须要安装中文分词器
                        .startObject("title").field("type", "text").field("store", true).field("analyzer", "ik_smart").endObject()
                        .startObject("price").field("type", "float").field("store", true).endObject()
                        .startObject("img").field("type", "text").field("store", true).endObject()
                        .startObject("description").field("type", "text").field("store", true).field("analyzer", "ik_smart").endObject()
                        .endObject()
                        .endObject()
                        .endObject();
                //设置规则 前提:库必须存在,才能创建规则,否则报错
                AcknowledgedResponse acknowledgedResponse = transportClient.admin().indices()
                        //设置索引库
                        .preparePutMapping(INDEX_NAME)
                        //给那个类型(表)添加规则
                        .setType(TABLE_NAME)
                        //关联规则
                        .setSource(xContentBuilder)
                        .get();
                System.out.println("索引规则创建成功="+acknowledgedResponse.isAcknowledged());

            }

        } catch (Exception e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            transportClient.close();
        }
    }


    public static void main(String[] args) {
    
    
        createIndexData();
    }

}

猜你喜欢

转载自blog.csdn.net/qq_42910468/article/details/107049665