版本:Elasticsearch 6.2.4。
Mapping类似于数据库中的表结构定义,主要作用如下:
Mapping完整的内容可以分为四部分内容:
如果没有手动设置Mapping,Elasticsearch默认会自动解析出类型,且每个字段以第一次出现的为准。
下面我们先看一下Elasticsearch默认创建的Mapping是什么样的。
首先我们创建一个索引:
PUT /user/
查询索引信息:
GET /user
结果:
{
"user": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1540044686190",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "_K5b8w7jRiuthf7QeQZhdw",
"version": {
"created": "5060299"
},
"provided_name": "user"
}
}
}
}
增加一条数据:
PUT /user/doc/1
{
"name":"Allen Yer",
"job":"php",
"age":22
}
PUT /user/doc/2
{
"name":"Allen Yer",
"job":0,
"age":22
}
查询数据是否新增成功:
GET /user/doc/_count
结果:
{
"count": 2,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
}
}
count为2,说明新增成功。然后我们查询下 mapping :
{
"user": {
"mappings": {
"doc": {
"properties": {
"age": {
"type": "long"
},
"job": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
发现自动为每个字段设置了类型:
name.keyword
字段,keyword
类型;job.keyword
字段,keyword
类型;虽然第二次数据新增是数字类型,但还是以第一次为主;大家可以把索引删掉,将新增数据调整为先新增第2条,再新增第一条,发现报错了:
DELETE /user
PUT /user/doc/2
{
"name":"Allen Yer",
"job":0,
"age":22
}
PUT /user/doc/1
{
"name":"Allen Yer",
"job":"php",
"age":22
}
报错:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "failed to parse [job]"
}
],
"type": "mapper_parsing_exception",
"reason": "failed to parse [job]",
"caused_by": {
"type": "number_format_exception",
"reason": "For input string: \"php\""
}
},
"status": 400
}
也能说明以第一次为主以字段第一次的值类型为准。这也说明了默认创建mapping可能不是我们想要的,这就需要手动创建mapping,好处有:
这次我们删掉mapping,并手动创建一个:
DELETE /user
PUT /user/
{
"mappings": {
"doc": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"age": {
"type": "long",
"index": false
},
"job": {
"type": "keyword"
},
"intro":{
"type":"text"
},
"create_time": {
"type": "date",
"format": "epoch_second"
}
}
}
}
}
字段类型说明:
注意:mapping生成后是不允许修改(包括删除)的。所以需要提前合理的的定义mapping。
该字段用于在没有指定具体字段的情况下进行模糊搜索,可以搜索全部字段的内容。
原理是将所有字段的内容视为字符串,拼在一起放在一个_all
字段上,但这个字段默认是不被存储的,可以被搜索。在query_string
与 simple_query_string
查询(Kibana搜索框用的这种查询方式)默认也是查询_all
字段。
6.x
版本被默认关闭。
相关设置:
PUT my_index
{
"mappings": {
"my_type": {
"_all": {
"enabled": true,
"store": false
},
"properties": {}
}
},
"settings": {
"index.query.default_field": "_all"
}
}
上述配置在5.x
版本是默认配置:
_all
字段_all
字段_all
字段如果从CPU性能及磁盘空间考虑,可以考虑可以完全禁用或基于每个字段自定义_all
字段。
假设_all
字段被禁用,则URI搜索请求、 query_string
和simple_query_string
查询将无法将其用于查询。我们可以将它们配置为其他字段:通过定义 index.query.default_field
属性。
这个字段用于存储原始的JSON文档内容,本身不会被索引,但是搜索的时候被返回。如果没有该字段,虽然还能正常搜索,但是返回的内容不知道对应的是什么。
示例:
GET /user/doc/_search?q=name
结果:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "user",
"_type": "doc",
"_id": "1",
"_score": 0.2876821,
"_source": {
"name": "this is test name",
"age": 22,
"job": "java",
"intro": "the intro can not be searched by singal",
"intro2": "去朝阳公园",
"create_time": 1540047542
}
}
]
}
}
搜索结果就包含_source
字段,存储的是原始文档内容。如果被禁用,只知道有匹配内容,但是无法知道返回的是什么。所以需要谨慎关闭该字段。
如果想禁用该字段,可以在创建Mapping的时候,设置_:
{
"mappings": {
"_doc": {
"_source": {
"enabled": false
}
}
}
}
ElasticSearch里面有 index 和 type 的概念:index称为索引,type为文档类型,一个index下面有多个type,每个type的字段可以不一样。这类似于关系型数据库的 database 和 table 的概念。
但是,ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。所以后来ElasticSearch团队想去掉type,于是在6.x版本为了向下兼容,一个index只允许有一个type。
该字段再在6.0.0中弃用。在Elasticsearch 6.x 版本中创建的索引只能包含单个type。在5.x中创建的含有多个type的索引将继续像以前一样在Elasticsearch 6.x中运行。type 将在Elasticsearch 7.0.0中完全删除。
详见:https://www.elastic.co/guide/...