基本概念
映射:
映射机制用于字段类型的确定,现在有的数据类型为string,date,number,booleans等。
分析:
分析机制用于进行全文分析的分词,以供建立检索、索引等操作用到的倒排索引。
1. 映射
1.1 映射带来的问题
因为ES会对各种字段进行类型的确定,每种类型的数据对应的索引方式也是不尽相同的,所以可能出现对两个字段中相同的数据进行索引时,因为字段对应数据类型对应的索引类型不一致,导致检索结果也不尽相同。
1.2 如果查看类型中字段对应的数据类型
命令:
GET /_index/_mapping/_type
样例:
{
"gb": {
"mappings": {
"tweet": {
"properties": {
"date": {
"type": "date",
"format": "dateOptionalTime"
},
"name": {
"type": "string"
},
"tweet": {
"type": "string"
},
"user_id": {
"type": "long"
}
}
}
}
}
}
默认字段_all没有显示,但是他是string类型
1.3 新概念 确切值和全文文本
确切值:比较的是二进制流
全文文本:比较的是匹配程度相关性的高低,文本分析会对文本进行文本分析,使用结果建立一个倒排索引。
1.4 倒排索引
作用:ES使用倒排索引这种结构来做快速索引
结构:由全文唯一的单词列表和每个单词所出现的位置组成。
倒排索引的形成需要用到分词这项技术,也称为将单词标准化或者表征化。同理,想要被查询的词语短句,也同样需要被标准化和表征化。
2. 分析和分析器
2.1 分析的过程
- 将文本进行表征化,成为适用于构建倒排索引的词(term)
- 然后标准化这些词,提高他们的可搜索性和匹配率。
以上的工作,就是由分析器完成的
2.2 分析器
分析器的功能有三个,其实也是三个步骤:
1. 文本过滤器 (我更喜欢称为文本处理器)
可以去除HTML的标记,还可将&转换成and单词等
2. 分词器
根据英文中的空格或者标点符号,进行单词的分词
3. 表征过滤(我更喜欢称为表征化)
将经过分词器的词语进行表征化,比如统一小写,增加同义词,转换同根词等。
2.3 查看分析器分析的结果
GET /_analyze?analyzer=standard
Text to analyze
结果:
{
"tokens": [
{
"token": "text", //实际被存储到索引中词
"start_offset": 0, //开始位置
"end_offset": 4, //结束位置
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "to",
"start_offset": 5,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "analyze",
"start_offset": 8,
"end_offset": 15,
"type": "<ALPHANUM>",
"position": 3
}
]
}
2.4 定制分析器
你不会总想所有的字段都接受分析,且都是相同的分析器
为了达到这种目的,我们需要人工的编写映射(mapping)
3. 人工编写的映射
3.1 为什么需要人为的编写映射
因为ES为我们创建的映射不一定符合我们的预期要求,但如果类型有出入的话,每种类型的索引方式本身就不一致,就会导致检索起来不符合预期要求。
3.2 字段对应映射的属性
每个字段有两个重要的属性:
1. type
2. index
type不用多言,index的意义为控制字段以何种方式索引,有这样几个值
值 | 意义 |
---|---|
analyzed | 索引这个字段,并且进行分析,按照相似程度进行匹配 |
not_analyzed | 索引但是不会进行分析,也就是按照确切值进行匹配 |
no | 不索引也不进行分析 |
string类型默认index为analyze,其他一些简单类型,interger,long,double,date的index值不包含analyze。
3.3 分词器的设置
一个字段的属性
{
"tweet": {
"type": "string",
"analyzer": "english"
}
}
其中的analyzer属性是可以设置的,比如standard、simple等
3.4 建立索引时设置属性
PUT /gb
{
"mapping":{
"tweet":{
"properties":{
"address":{
"type":"string",
"analyzer":"english"
},
"name":{
"type":"string"
},
"date":{
"type":"date"
},
"user_id":{
"type":"long"
}
}
}
}
}
相当于设置 /gb/tweet/的格式
字段类型一旦设置,不能被更改!
因为类型改变,索引类型也会相应的改变,那么已经被索引的数据就无法再正确检索、索引!
但是允许添加字段
PUT /gb/_mapping/tweet
{
"properties":{
"tags":{
"type":"string",
"analyzer":"not_anaylzed"
}
}
}
4. 复合类型
4.1 多值字段
就是数组,数组中每个元素的类型由第一个元素决定
4.2 空字段
"empty_string":""
"empty_array":[]
"null_value":null
"array_with_null_value":[ null ]
4.4 对象如何索引
文档
{
"tweet": "Elasticsearch is very flexible",
"user": {
"id": "@johnsmith",
"gender": "male",
"age": 26,
"name": {
"full": "John Smith",
"first": "John",
"last": "Smith"
}
}
}
mapping
{
"gb": {
"tweet": { <1>
"properties": {
"tweet": { "type": "string" },
"user": { <2>
"type": "object",
"properties": {
"id": { "type": "string" },
"gender": { "type": "string" },
"age": { "type": "long" },
"name": { <2>
"type": "object",
"properties": {
"full": { "type": "string" },
"first": { "type": "string" },
"last": { "type": "string" }
}
}
}
}
}
}
}
}
ES内部如何进行索引
{
"tweet": [elasticsearch, flexible, very],
"user.id": [@johnsmith],
"user.gender": [male],
"user.age": [26],
"user.name.full": [john, smith],
"user.name.first": [john],
"user.name.last": [smith]
}
类似于运用了全限定名。