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
2
3
4
5
6
7
8
PUT movies
{
"mappings": {
"_doc": {
"dynamic": "false" // true, false, strict
}
}
}

如果是新增字段

  • 如果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
2
GET /megacrp/_mapping
GET /megacrp/employee/_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
    15
    PUT /gb
    {
    "mappings": {
    "testmapping" : {
    "properties" : {
    "tweetgjghjggh" : {
    "type" : "text",
    "analyzer": "english"
    },
    "date" : {
    "type" : "date"
    },
    "user_id" : {
    "type" : "long"
    }}}}}