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

    技术2022-07-10  139

    简单记录一下

    错误说明:此错误是发生在使用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(); } }
    Processed: 0.018, SQL: 12