类似于数据库的schema的定义,mapping会把文档映射成lucene需要的扁平格式,一个mapping属于一个索引的type,一个type中有一个mapping定义,7.0后一个索引只有一个type,所以不需要在mapping中定义type的信息。作用如下:
定义索引这里面的字段和名称
定义字段的数据类型,字符串、布尔、数字…
字段,倒排索引相关的配置,是否分词。
{
"mappings":{
"_doc":{
"_all":{
"enabled":false #默认情况,ElasticSarch自动使用_all所有的文档的域都会被加到_all中进行索引。可以使用"_all" : {"enabled":false} 开关禁用它。如果某个域不希望被加到_all中,可以使用"include_in_all":false关闭
},
"properties":{
"uuid":{
"type":"text",
"copy_to":"_search_all", #对应_search_all字段,可以对其进行全文检索
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":150 #ignore_above 默认值是256,当字段文本的长度大于指定值时,不做倒排索引。
}
}
},
"name":{
"type":"text",
"copy_to":"_search_all",
"analyzer":"ik_max_word", # ik_max_word 插件会最细粒度分词
"search_analyzer":"ik_smart", # ik_smart 粗粒度分词
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":150
}
}
},
"dt_from_explode_time":{
"type":"date",
"copy_to":"_search_all",
"format":"strict_date_optional_time||epoch_millis"
},
"_search_all":{
"type":"text"
}
},
"date_detection":false, #关闭日期自动检测,如果开启,会对于设置为日期格式的字段进行判断
"dynamic_templates":[ #用于自定义在动态添加field的时候自动给field设置的数据类型
{
"strings":{
"match_mapping_type":"string",
"mapping":{
"type":"text",
"copy_to":"_search_all",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":150
}
}
}
}
}
]
}
},
"settings":{
"index":{
"number_of_shards":6, #分片数量
"number_of_replicas":1 #副本数量
}
}
}
分词:
按照一般情况来讲,索引分词应该按照最细粒度来分词,搜索分词可按最粗粒度来分词
比如搜索“华为手机”
用户不希望将关键词拆分为华为,手机,那这样各类手机和华为路由器或华为其它产品也能搜索出来
所以这块建议搜索分词设置为最粗粒度
字段类型概述
一级分类 | 二级分类 | 具体类型 |
---|---|---|
核心类型 | 字符串类型 | |
整数类型 | integer,long,short,byte | |
浮点类型 | double,float,half_float,scaled_float | |
逻辑类型 | boolean | |
日期类型 | date | |
范围类型 | range | |
二进制类型 | binary | |
复合类型 | 数组类型 | array |
对象类型 | object | |
嵌套类型 | nested | |
地理类型 | 地理坐标类型 | geo_point |
地理地图 | geo_shape | |
特殊类型 | IP类型 | ip |
范围类型 | completion | |
令牌计数类型 | token_count | |
附件类型 | attachment | |
抽取类型 | percolator |
string类型:ELasticsearch 5.X之后的字段类型不再支持string,由text或keyword取代。 如果仍使用string,会给出警告
text取代了string,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合(termsAggregation除外)
keyword类型适用于索引结构化的字段,比如email地址、主机名、状态码和标签。如果字段需要进行过滤(比如查找已发布博客中status属性为published的文章)、排序、聚合。keyword类型的字段只能通过精确值搜索到
写入文档的时候,索引不存在,会自动创建索引, 无需手动创建,ES会根据内容推断字段的类型,推断会不准确,可能造成某些功能无法使用,例如 范围查询。
查看一个索引当前的mapping
GET /movies/_mapping
在写入文档的时候,有可能当前文档的索引并不存在,就会为我们自动创建索引
DynamicMapping使得我们无需手动定义Mapping字段信息,ES根据文档的信息来推断出文档的类型。
ES推算的字段类型并不完全准确。
当类型设置的不对时,有些功能无法正常运行,比如聚合、分词、范围查询等等。
新增字段
dynamic设置为true,一旦有新增字段的文档写入,mapping也同时被更新。
dynamic设置为false,mapping不会被更新,新增的字段数据无法被索引,但是信息会出现在source中.
dynamic设置为strict,文档写入失败
已有的字段,一旦有数据写入,不支持修改(倒排索引不支持修改)
希望更改字段类型,用Reindex API,重建索引
设计原因
如果修改字段数据类型,会导致已经被索引的文档不能被搜索。
新增字段不存在影响。
注意:SpringDataElasticsearch底层使用的不是Elasticsearch提供的RestHighLevelClient,而是TransportClient,并不采用Http协议通信,而是访问elasticsearch对外开放的tcp端口
spring:
data:
elasticsearch:
cluster-name: myescluster
cluster-nodes: ip1:9300, ip2:9300, ip3:9300
index-name: test
@Component
@Data
public class AppConfig {
@Value("${spring.data.elasticsearch.index-name}")
private String indexName;
}
/**
* MyObject实体
*
*/
@Data
@Document(indexName = "#{appConfig.indexName}", type = "myObject")
public class MyObject {
@Id
@Field(index = false, store = true, type = FieldType.Keyword)
private String tid;
@Field(index = true, store = true, analyzer = "ik", searchAnalyzer = "ik", type = FieldType.Text)
private String title;
@Field(index = true, store = true, analyzer = "ik", searchAnalyzer = "ik", type = FieldType.Text)
private String content;
@Field(index = false, store = true, type = FieldType.Date, format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss")
private Date time;
}
@Document:声明索引库配置
indexName:索引库名称
type:类型名称,默认是“docs”
shards:分片数量,默认5
replicas:副本数量,默认1
@Id:声明实体类的id
@Field:声明字段属性
type:字段的数据类型
analyzer:指定分词器类型
index:是否创建索引
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringElasticsearchTest {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
/**
* 创建索引和映射
*/
@Test
public void testCreateMappingAndIndex(){
try {
elasticsearchTemplate.putMapping(MyObject .class);
} catch (Exception e) {
elasticsearchTemplate.createIndex(MyObject .class);
elasticsearchTemplate.putMapping(MyObject .class);
}
}
/**
* 创建索引库
*/
@Test
public void testCreateIndex(){
// 创建索引库,并制定实体类的字节码
elasticsearchTemplate.createIndex(MyObject .class);
}
/**
* 创建映射
*/
@Test
public void testCreateMapping(){
// 创建索引库,并制定实体类的字节码
elasticsearchTemplate.putMapping(MyObject .class);
}
}