映射(mapping)

人盡茶涼 提交于 2019-12-25 00:49:37

就像是在 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:

string

Whole number:

byteshortintegerlong

Floating point:

floatdouble

Boolean:

boolean

Date:

date

当你index一个包含了新类型的document的时候——也就是上面表格中没有提到的——ES就会使用根据 dynamic mapping 从JSON中的数据类型尝试猜测filed的type:

JSON type:

Field type:

Boolean: true or false

"boolean"

Whole number: 123

"long"

Floating point: 123.45

"double"

String, valid date: "2014-09-15"

"date"

String: "foo bar"

"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=tweetBlack-cats GET /gb/_analyze?field=tagBlack-cats 

这个tweet字段产生了两个term“black”和“cat",然而tagfield产生了单个的term”Black-cat“。换句话说就是,我们的mapping已经正常工作了。

 

原文:http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/mapping-intro.html

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!