ES1_3映射
常用操作 - 映射(Mapping)
映射的定义
映射就像数据库中的 schema ,描述了数据在每个字段内如何存储,包括文档可能具有的字段或 属性 、 每个字段的数据类型—比如 string, integer 或 date —以及 Lucene 是如何索引和存储这些字段的。
Lucene 也没有映射的概念,映射是 Elasticsearch 将复杂 JSON 文档 映射 成 Lucene 需要的扁平化数据的方式。
- 比如下面的索引名叫 data,其中定义了 people 和 transactions 类型:会被转换为类似下面的映射保存:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27{
"data": {
"mappings": {
"people": {
"properties": {
"name": {
"type": "string",
},
"address": {
"type": "string"
}
}
},
"transactions": {
"properties": {
"timestamp": {
"type": "date",
"format": "strict_date_optional_time"
},
"message": {
"type": "string"
}
}
}
}
}
}所以虽然创建一个文档后其类型就确定了,但是实际上这个文档所占用的空间是该索引内所有字段的总和。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22{
"data": {
"mappings": {
"_type": {
"type": "string",
"index": "not_analyzed"
},
"name": {
"type": "string"
}
"address": {
"type": "string"
}
"timestamp": {
"type": "long"
}
"message": {
"type": "string"
}
}
}
}
所以有一条建议:一个索引中的类型应当都是相似的,他们有类似的字段,比如 man 和 woman 共享 name 属性;如果两个类型的字段集互不相同,创建一个 类型的文档后将浪费很多空间,而是应该将他们分到不同的索引中。
动态映射机制
在索引一个新的文档时,es 会自动为每个字段推断类型,这个过程称为动态映射。这意味着如果你通过引号( “123” )索引一个数字,它会被映射为 string 类型,而不是 long 。但是,如果这个域已经映射为 long ,那么 Elasticsearch 会尝试将这个字符串转化为 long ,如果无法转化,则抛出一个异常。
1 | PUT movies |
如果是新增字段
- 如果Dynamic设置为true,一旦有新增字段的文档写入,Mapping会被同时更新
- 如果Dynamic设置为false,Mapping不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
- 如果Dynamic被设置为strict,则文档写入失败
如果是更新字段
- 对已有字段,一旦有数据写入,就不再支持修改字段定义
- 如果希望改变字段类型,必须reindex重建索引
数组
ES不提供专门的数组类型,但是每个字段都可以包含多个相同类型的数值,所以ES天然是支持数组类型的。
多字段类型
有时候我们希望一个字段可以被多种方式检索,比如:
- 通过不同语言检索
- pinyin字段的搜索
- 还支持为搜索和索引指定不同的analyzer
一些默认的映射
布尔型: true 或者 false | boolean
整数: 123 | long
浮点数: 123.45 | double
字符串,有效日期: 2014-09-15 | date
字符串: foo bar | string
整数 : byte, short, integer
浮点数: float
自定义映射
TODO
全文字符串域和精确值字符串域的区别
使用特定语言分析器
优化域以适应部分匹配
指定自定义数据格式
查看映射
1 | GET /megacrp/_mapping |
返回属性包括:
- index 属性控制怎样索引字符串
- analyzed 分析字符串再索引(全文索引),字符串且只有字符串可以取这个属性
- not_analyzed 不分析、直接索引精确值
- no 不索引、不能被搜索到
- analyzer 对于 analyzed 字符串域,用 analyzer 属性指定在搜索和索引时使用的分析器,默认时 standard
更新映射
- 可以通过更新一个映射来添加一个新域,并为其设置映射(后来版本取消了 string 类型,改成了text,要注意)
- 不能将一个存在的域从 analyzed 改为 not_analyzed。因为如果一个域的映射已经存在,那么该域的数据可能已经被索引。如果你意图修改这个域的映射,索引的数据可能会出错,不能被正常的搜索。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15PUT /gb
{
"mappings": {
"testmapping" : {
"properties" : {
"tweetgjghjggh" : {
"type" : "text",
"analyzer": "english"
},
"date" : {
"type" : "date"
},
"user_id" : {
"type" : "long"
}}}}}