就像是在 Data
in, data out中解释过的,index中的每个document都有type。每个type都有自己的mapping或者schema
definition。在type中mapping定义filed,定义每个filed中的数据类型,定义ES怎么处理这个filed,mapping也用于配置与该类型相关联的元数据。
我们会在 Types
and Mappings中详细的讨论mapping,在这个章节,我们就是能让你足够开始就行了。
core simple field types
ES支持下面的简单的filed type:
String: |
|
Whole number: |
|
Floating point: |
|
Boolean: |
|
Date: |
|
当你index一个包含了新类型的document的时候——也就是上面表格中没有提到的——ES就会使用根据 dynamic
mapping 从JSON中的数据类型尝试猜测filed的type:
JSON type: |
Field type: |
Boolean: |
|
Whole number: |
|
Floating point: |
|
String, valid date: |
|
String: |
|
也就是说,如果你index一个使用双引号包括起来的数字,它就会成为一个string,而不是long。然而如果这个field已经被mapping映射成了long,ES会尝试向long进行转换,如果不行则会报异常。
viewing the mapping
我们可以查看ES已经拥有的mapping,无论这个mapping是映射到一个type还是多个type,无论是一个index还是多个index。使用/_mapping作为请求的结束。在 start
of this chapter中我们已经检索过gb中的tweet的mapping:
GET /gb/_mapping/tweet
返回值展示了ES根据index的document动态生成的field的mapping(就是properties属性):
{
"gb":{
"mappings":{
"tweet":{
"properties":{
"date":{
"type":"date",
"format":"dateOptionalTime"
},
"name":{
"type":"string"
},
"tweet":{
"type":"string"
},
"user_id":{
"type":"long"
}
}
}
}
}
}
不正确的mapping,比如把age映射为string而不是integer,就会对查询产生混淆的结果。
customizing field mappings
field的最重要的属性就是type,对于不是string类型的field,除了type,你几乎很少会mapping其他的属性。
{
"number_of_clicks":{
"type":"integer"
}
}
string类型的field,默认的被当中full text的类型,就是说在存储之前他们的值要经过分词器进行分词,并且对full
text的检索也要经过相同的分词器进行分词。
对于string类型来说两个最重要的mapping属性就是index和analyzer。
index
这个属性控制着string是怎么存储的。其值是一下三个中的一个,
1:analyzed——首先对其进行分词,然后存储,就是把这个field作为full text。
2:not_analyzed——存储这个field,让其可搜索,但是要确切的存储,不要对其进行分词。
3:no——不要存储这个field。这个field也是不可搜索的。
默认值是analyzed。如果你想把他当作是确切的值,你需要如下设置:
{
"tag":{
"type": "string",
"index": "not_analyzed"
}
}
其他的简单的类型——long,double,date等——也接受index这个参数,但是值只有no和not_analyzed,因为他们的值是不可以analyzed的。
analyzer
对于string
field,使用analyzed属性是指定index和search的时候要应用的分词器,默认ES使用standard,但是你可以修改这个属性的值,比如:whitespace,simple,english:
{
"tweet":{
"type": "string",
"analyzer":"english"
}
}
在 Custom
analyzers 中我们会介绍怎么自定义一个analyzed。
Updating a mapping
当你在第一次创建index的时候你可以指定一个mapping。当然,你也可以使用/_mapping对一个新的type添加mapping(或者是一个已经存在的type的mapping)
。
一旦你添加一个mapping,就最好不要修改他,如果一个field已经被mapping,有可能这个filed已经存储的有数据了,如果这个时候修改这个filed的mapping,先前的被index的数据将会导致错误从而变得不可搜索。
你可以对新添加的field更新mapping,但是最好不要把已经存在的field从analyzed便更为not_analyzed。
为了演示所有指定mapping的方式,我们首先删除gb这个index:
DELETE /gb
然后创建一个新的index,指定tweet字段使用english分词器:
PUT /gb
{
"mappings":{
"tweet":{
"properties":{
"tweet":{
"type": "string",
"analyzer":"english"
},
"date":{
"type": "date"
},
"name":{
"type": "string"
},
"user_id":{
"type": "long"
}
}
}
}
}
标记1处表示使用指定mapping创建index。
接着,我们向tweet添加一个名为tag的field,并且向新的字段添加not_analyzed属性:
PUT /gb/_mapping/tweet
{
"properties":{
"tag":{
"type": "string",
"index": "not_analyzed"
}
}
}
现在,我们不需要列出已经存在的field,因为我们不能修改他们了,我们的新的field已经合并到已经存在的mapping中了。
Testing the mapping
你能通过field name使用analyze API测试mapping。比较一下两个请求的输出:
GET /gb/_analyze?field=tweet
Black-cats
GET /gb/_analyze?field=tag
Black-cats
这个tweet字段产生了两个term“black”和“cat",然而tagfield产生了单个的term”Black-cat“。换句话说就是,我们的mapping已经正常工作了。
原文:http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/mapping-intro.html