es创建索引(mapping和setting)

文章介绍了如何在Elasticsearch中创建person_news索引,包括字段定义(如companyName、newsTitle等)、数据结构(如nested嵌套字段)以及使用不同分词器(ik_max_word、ik_smart和standard)处理中文文本。通过示例展示了如何插入数据和分析分词效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、首先定义一个索引,如下

PUT /person_news
{
  "settings": {
    "index": {
      "number_of_shards": "3",
      "number_of_replicas": "0",
      "max_result_window": "2000000000"
    }
  },
  "mappings": {
    "properties": {
      "companyName": {
        "type": "text",
	"analyzer": "ik_max_word",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "newsSource": {
        "type": "keyword"
      },
      "newsContent": {
        "type": "text",
	"analyzer": "ik_max_word"
      },
      "newsTitle": {
        "type": "text",
	"analyzer": "ik_max_word",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "labels": {
        "type": "keyword"
      },
      "personInfo": {
        "type": "nested",
        "properties": {
          "personName": {
            "type": "keyword"
          },
          "age": {
            "type": "integer"
          }
        }
      },
      "hotPoint": {
        "type": "long"
      }
    }
  }
}

person_news 这个索引是新闻和人相关的索引,companyName公司名称,定义了text类型,分词器采用的是ik分词,同时定义子字段类型为keyword,表示不分词(可以用来聚合和精准匹配);
newsSource 新闻来源,不分词;
newsContent 新闻内容,分词;
newsTitle 新闻标题,分词,同时建立子字段为keyword类型(同上companyName);
labels 标签,不分词(这里我准备给这个字段存储的是一个数组类型,就是一个新闻有多个标签,详见下文插入文档);
personInfo 新闻中的人物对象信息,采用的是nested结构,是一个数组对象,对象里面有personName和age字段;
hotPoint 新闻的热点值,通常通过此字段给新闻排序;
2、插入数据

PUT person_news/_doc/1
{
  "companyName": "中国恒大有限责任公司",
  "newsSource": "新华社",
  "newsContent": "今日中国证监会对中国恒大董事长许家印罚款4000万,并对其做出终身不能入市的处罚规定,其公司其他高管夏海钧也被做出相应处罚",
  "newsTitle": "恒大许家印被罚",
  "labels": [
    "恒大",
    "许家印"
  ],
  "personInfo": [
    {
      "personName": "许家印",
      "age": 60
    },
    {
      "personName": "夏海钧",
      "age": 59
    }
  ],
  "hotPoint": 1
}
PUT person_news/_doc/2
{
  "companyName": "阿里巴巴有限责任公司",
  "newsSource": "新华社",
  "newsContent": "今日阿里公司集团董事长张勇卸任,由蔡崇信接任",
  "newsTitle": "阿里张勇卸任",
  "labels": [
    "阿里",
    "蔡崇信",
    "张勇"
  ],
  "personInfo": [
    {
      "personName": "张勇",
      "age": 60
    },
    {
      "personName": "蔡崇信",
      "age": 54
    }
  ],
  "hotPoint": 2
}

PUT person_news/_doc/3
{
  "companyName": "中国恒大有限责任公司",
  "newsSource": "路透社",
  "newsContent": "中国恒大董事长传闻跳楼,恒大资产负债高达几万亿,传闻阿里张勇将对恒大进行投资,进军房地产,具体消息恒大高管夏海钧予以否认",
  "newsTitle": "恒大董事长许家印",
  "labels": [
    "恒大",
    "张勇"
  ],
  "personInfo": [
    {
      "personName": "张勇",
      "age": 54
    },
    {
      "personName": "夏海钧",
      "age": 59
    }
  ],
  "hotPoint": 3
}

3、可以通过kibana的DSL语句,查看文本采用某个分词器的效果(采用的是ik_max_word最大粒度分词)

GET /person_news/_analyze
{
  "analyzer": "ik_max_word",
  "text": "中国恒大有限责任公司"
}

结果如下:

{
  "tokens" : [
    {
      "token" : "中国",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "恒",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "大有",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "有限责任",
      "start_offset" : 4,
      "end_offset" : 8,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "有限",
      "start_offset" : 4,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "责任",
      "start_offset" : 6,
      "end_offset" : 8,
      "type" : "CN_WORD",
      "position" : 5
    },
    {
      "token" : "公司",
      "start_offset" : 8,
      "end_offset" : 10,
      "type" : "CN_WORD",
      "position" : 6
    }
  ]
}

采用ik_smart智能分词

{
  "tokens" : [
    {
      "token" : "中国",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "恒",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "大",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "CN_CHAR",
      "position" : 2
    },
    {
      "token" : "有限责任",
      "start_offset" : 4,
      "end_offset" : 8,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "公司",
      "start_offset" : 8,
      "end_offset" : 10,
      "type" : "CN_WORD",
      "position" : 4
    }
  ]
}

使用es自带的默认分词器,分词效果如下(会把每个中文分成一个个的汉字)

GET /person_news/_analyze
{
  "analyzer": "standard",
  "text": "中国恒大有限责任公司"
}
{
  "tokens" : [
    {
      "token" : "中",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "国",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "恒",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    },
    {
      "token" : "大",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "<IDEOGRAPHIC>",
      "position" : 3
    },
    {
      "token" : "有",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "<IDEOGRAPHIC>",
      "position" : 4
    },
    {
      "token" : "限",
      "start_offset" : 5,
      "end_offset" : 6,
      "type" : "<IDEOGRAPHIC>",
      "position" : 5
    },
    {
      "token" : "责",
      "start_offset" : 6,
      "end_offset" : 7,
      "type" : "<IDEOGRAPHIC>",
      "position" : 6
    },
    {
      "token" : "任",
      "start_offset" : 7,
      "end_offset" : 8,
      "type" : "<IDEOGRAPHIC>",
      "position" : 7
    },
    {
      "token" : "公",
      "start_offset" : 8,
      "end_offset" : 9,
      "type" : "<IDEOGRAPHIC>",
      "position" : 8
    },
    {
      "token" : "司",
      "start_offset" : 9,
      "end_offset" : 10,
      "type" : "<IDEOGRAPHIC>",
      "position" : 9
    }
  ]
}

<think>好的,用户之前询问了Elasticsearch索引模板,现在又转向了Spring Data Elasticsearch如何创建索引。我需要先理解用户的需求。用户可能是在开发中使用Spring Data Elasticsearch,想要了解如何通过这个框架来创建索引,而不仅仅是Elasticsearch原生的方法。 首先,我需要回忆Spring Data Elasticsearch的基本概念。它简化了Elasticsearch的操作,通过注解模板类让Java开发者更方便地与ES交互。用户可能已经知道ES的基本操作,现在想结合Spring框架来使用,特别是在创建索引方面。 接下来,用户可能想知道如何通过实体类自动创建索引,或者手动创建。需要覆盖这两种情况。Spring Data Elasticsearch通常使用@Document注解来定义索引,然后通过ElasticsearchOperations或ElasticsearchRestTemplate来操作。 另外,用户可能关心索引的配置,比如分片、副本、映射等。需要解释如何通过注解设置这些参数,或者通过IndexOperations进行手动设置。 可能用户在实际应用中遇到了问题,比如索引无法自动创建,或者映射不正确,因此需要详细的步骤示例代码。需要提供具体的代码示例,包括实体类定义、配置类、自动创建索引的方法,以及手动创建的方式。 还要考虑版本兼容性。不同版本的Spring Data Elasticsearch可能API有所不同,需要指出常见的版本差异,比如4.x5.x的变化,避免用户混淆。 另外,用户可能对动态模板或索引模板在Spring中的使用有疑问,虽然之前的问题是关于ES原生的索引模板,现在结合Spring框架,可能需要说明如何整合两者,比如在Spring应用中应用索引模板。 最后,需要提醒用户注意事项,比如确保ES服务可用,配置正确,版本匹配,以及自动创建的限制,比如需要实体类有@Document注解,并且正确配置了映射。 总结下来,回答的结构应该包括自动创建手动创建两种方式,示例代码,版本注意事项,以及常见问题解决方案。确保内容清晰,步骤明确,帮助用户顺利实现索引创建。</think>以下是关于 **Spring Data Elasticsearch 创建索引** 的详细介绍,涵盖自动/手动创建索引的步骤、核心注解及实际代码示例: --- ### **一、创建索引的两种方式** Spring Data Elasticsearch 支持 **自动创建索引** **手动编程创建索引**,具体选择取决于业务场景需求。 --- ### **二、自动创建索引** 通过 **实体类注解** 定义索引配置,Spring Data Elasticsearch 会在应用启动时自动创建索引(需配置 `@EnableElasticsearchRepositories`)。 #### **1. 核心注解** | 注解 | 说明 | |----------------------|----------------------------------------------------------------------| | `@Document` | 标记实体类对应的 Elasticsearch 索引。 | | `@Id` | 标识主键字段。 | | `@Field` | 定义字段类型、分词器等映射规则。 | | `@Setting` | 定义索引的 `settings`(如分片数、副本数、分词器等)。 | #### **2. 示例代码** ```java // 实体类定义 @Document(indexName = "user_index", createIndex = true) // createIndex=true 表示自动创建索引 @Setting( shards = 3, replicas = 1, settingPath = "/elasticsearch/custom_analyzer.json" // 自定义分词器配置文件 ) public class User { @Id private String id; @Field(type = FieldType.Text, analyzer = "ik_max_word") private String name; @Field(type = FieldType.Integer) private Integer age; // Getters & Setters } ``` #### **3. 自动创建索引的条件** - **启动配置**:在 Spring Boot 主类添加 `@EnableElasticsearchRepositories`。 - **依赖正确**:确保引入 `spring-boot-starter-data-elasticsearch`。 - **索引不存在**:若索引已存在,不会覆盖原有配置。 --- ### **三、手动创建索引** 通过 `ElasticsearchOperations` 或 `IndexOperations` 手动控制索引创建配置。 #### **1. 使用 IndexOperations** ```java @Autowired private ElasticsearchOperations elasticsearchOperations; public void createUserIndex() { IndexOperations indexOps = elasticsearchOperations.indexOps(User.class); // 删除索引(如果存在) if (indexOps.exists()) { indexOps.delete(); } // 创建索引并配置映射 indexOps.create(); indexOps.putMapping(User.class); // 自定义 settings(可选) Settings settings = Settings.builder() .put("index.number_of_shards", 3) .put("index.number_of_replicas", 1) .build(); indexOps.create(settings); } ``` #### **2. 直接使用 Elasticsearch REST Client** 若需要更底层控制,可直接操作 `RestHighLevelClient`: ```java @Autowired private RestHighLevelClient restHighLevelClient; public void createIndexWithCustomSettings() throws IOException { CreateIndexRequest request = new CreateIndexRequest("custom_index"); // 设置分片副本 request.settings(Settings.builder() .put("index.number_of_shards", 3) .put("index.number_of_replicas", 1) ); // 定义映射 XContentBuilder mappingBuilder = XContentFactory.jsonBuilder() .startObject() .startObject("properties") .startObject("name") .field("type", "text") .field("analyzer", "ik_max_word") .endObject() .endObject() .endObject(); request.mapping(mappingBuilder); // 执行创建 restHighLevelClient.indices().create(request, RequestOptions.DEFAULT); } ``` --- ### **四、动态映射与模板整合** 若需结合 **Elasticsearch 索引模板**(Index Templates),可在 Spring 中配置: #### **1. 预定义索引模板** 在 Elasticsearch 中预先创建模板(如 `PUT /_index_template/user_template`),模板的 `index_patterns` 需匹配 Spring 实体类的索引名称(例如 `user_*`)。 Spring Data Elasticsearch 创建索引时,会自动应用匹配的模板。 #### **2. 动态模板配置** 在实体类中使用 `@DynamicMapping` 注解,或在 `@Field` 中定义动态规则: ```java @Document(indexName = "log_index") public class Log { @Field(type = FieldType.Date, format = DateFormat.date_optional_time) private Date timestamp; @Dynamic(value = DynamicMapping.STRICT) // 禁止动态添加字段 private Map<String, Object> metadata; } ``` --- ### **五、版本兼容性注意** 不同版本的 Spring Data ElasticsearchElasticsearch 客户端的支持不同: - **Spring Data Elasticsearch 4.x**:兼容 Elasticsearch 7.x。 - **Spring Data Elasticsearch 5.x**:兼容 Elasticsearch 8.x,需使用新的 `ElasticsearchClient`。 --- ### **六、常见问题** #### **1. 索引未自动创建** - 检查 `@Document(createIndex = true)` 是否设置。 - 确认 `spring.data.elasticsearch.client.reactive.enabled=false`(若使用阻塞式客户端)。 #### **2. 字段映射不生效** - 确保 `@Field` 注解中的 `type` 正确(如 `FieldType.Keyword` 或 `FieldType.Text`)。 - 检查是否手动覆盖了自动生成的映射。 #### **3. 版本冲突** - 确保 Spring Data Elasticsearch 版本与 Elasticsearch 服务端版本匹配([官方兼容性矩阵](https://spring.io/projects/spring-data-elasticsearch))。 --- ### **七、完整配置示例(application.yml)** ```yaml spring: data: elasticsearch: client: reactive: endpoints: localhost:9200 # Elasticsearch 地址 repositories: enabled: true ``` --- 如果需要更详细的代码示例或特定场景的配置(如多租户索引、别名管理),可以进一步探讨!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值