mapping

类似于数据库的schema的定义,mapping会把文档映射成lucene需要的扁平格式,一个mapping属于一个索引的type,一个type中有一个mapping定义,7.0后一个索引只有一个type,所以不需要在mapping中定义type的信息。作用如下:

定义索引这里面的字段和名称
定义字段的数据类型,字符串、布尔、数字…
字段,倒排索引相关的配置,是否分词。

mapping的基本格式

{
    "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  #副本数量
        }
    }
}

分词:

按照一般情况来讲,索引分词应该按照最细粒度来分词,搜索分词可按最粗粒度来分词
比如搜索“华为手机”
用户不希望将关键词拆分为华为,手机,那这样各类手机和华为路由器或华为其它产品也能搜索出来
所以这块建议搜索分词设置为最粗粒度

mapping的参数说明

字段类型概述

一级分类二级分类具体类型
核心类型字符串类型string,text,keyword
整数类型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类型的字段只能通过精确值搜索到

Dynamic Mapping

写入文档的时候,索引不存在,会自动创建索引, 无需手动创建,ES会根据内容推断字段的类型,推断会不准确,可能造成某些功能无法使用,例如 范围查询。

查看一个索引当前的mapping

GET /movies/_mapping

修改Mapping的字段类型

在写入文档的时候,有可能当前文档的索引并不存在,就会为我们自动创建索引
DynamicMapping使得我们无需手动定义Mapping字段信息,ES根据文档的信息来推断出文档的类型。
ES推算的字段类型并不完全准确。
当类型设置的不对时,有些功能无法正常运行,比如聚合、分词、范围查询等等。

新增字段
dynamic设置为true,一旦有新增字段的文档写入,mapping也同时被更新。
dynamic设置为false,mapping不会被更新,新增的字段数据无法被索引,但是信息会出现在source中.
dynamic设置为strict,文档写入失败
已有的字段,一旦有数据写入,不支持修改(倒排索引不支持修改)
希望更改字段类型,用Reindex API,重建索引
设计原因
如果修改字段数据类型,会导致已经被索引的文档不能被搜索。
新增字段不存在影响。

SpringDataElasticsearch操作Elasticsearch创建索引库以及创建映射

注意:SpringDataElasticsearch底层使用的不是Elasticsearch提供的RestHighLevelClient,而是TransportClient,并不采用Http协议通信,而是访问elasticsearch对外开放的tcp端口

spring:
  data:
    elasticsearch:
      cluster-name: myescluster
      cluster-nodes: ip1:9300, ip2:9300, ip3:9300
      index-name: test

JavaConfig定义

@Component
@Data
public class AppConfig {

    @Value("${spring.data.elasticsearch.index-name}")
    private String indexName;
}

pojo

/**
 * 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);
    }
}


Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐