我们很少确切的匹配整个全文文本。我们想在全文中查询包含查询文本的部分。不仅如此,我们还期望搜索引擎能理解我们 的意图,例:

ESXI 映射LUN 不大于 esxi usb映射_数组


为了方便在全文文本字段中进行这些类型的查询,Elasticsearch首先对文本分析(analyzes),然后使用结果建立一个倒排索 引

1. 倒排索引

Elasticsearch使用一种叫做倒排索引(inverted index)的结构来做快速的全文搜索。倒排索引由在文档中出现的唯一的单词列 表,以及对于每个单词在文档中的位置组成。
例如,我们有两个文档,每个文档 content 字段包含:

1. The quick brown fox jumped over the lazy dog
2. Quick brown foxes leap over lazy dogs in summer

我们将词为统一为标准格式,这样就可以找到不是确切匹配查询,但是足以相似从而可以关联的文档

例如:

ESXI 映射LUN 不大于 esxi usb映射_字段_02


现在的索引:

ESXI 映射LUN 不大于 esxi usb映射_Elastic_03


例如:我们要搜索 “+Quick +fox” ,查询将变成 “+quick +fox” ,这样就可以匹配到两个文档。

这很重要。你只可以找到确实存在于索引中的词,所以索引文本和查询字符串都要标准化为相同的形式。

这个表征化和标准化的过程叫做分词(analysis)

2. 标准分析器

标准分析器是Elasticsearch默认使用的分析器。对于文本分析,它对于任何语言都是最佳选择(译者注:就是没啥特殊需 求,对于任何一个国家的语言,这个分析器就够用了)。它根据Unicode Consortium的定义的单词边界(word boundaries) 来切分文本,然后去掉大部分标点符号。最后,把所有词转为小写。
例:“Set the shape to semi-transparent by calling set_trans(5)”

分析后:

set, the, shape, to, semi, transparent, by, calling, set_trans, 5

当我们索引(index)一个文档,全文字段会被分析为单独的词来创建倒排索引

ESXI 映射LUN 不大于 esxi usb映射_ESXI 映射LUN 不大于_04

用 analyze API来查看文本是如何被分析的。在查询字符串参数中指定要使用的分析器,被分析的文本做为请求体:

ESXI 映射LUN 不大于 esxi usb映射_Elastic_05


ESXI 映射LUN 不大于 esxi usb映射_数组_06


token 是一个实际被存储在索引中的词。

position 指明词在原文本中是第几个出现的。

start_offset 和 end_offset 表示词 在原文本中占据的位置。

3. 映射

索引中每个文档都有一个类型(type)。 每个类型拥有自己的映射(mapping)或者模式定义 (schema definition)。一个映射定义了字段类型,每个字段的数据类型,以及字段被Elasticsearch处理的方式。映射还用于 设置关联到类型上的元数据。

Elasticsearch支持以下简单字段类型:

ESXI 映射LUN 不大于 esxi usb映射_ESXI 映射LUN 不大于_07


当你索引一个包含新字段的文档——一个之前没有的字段——Elasticsearch将使用动态映射猜测字段类型,这类型来自于 JSON的基本数据类型,使用以下规则:

ESXI 映射LUN 不大于 esxi usb映射_ESXI 映射LUN 不大于_08


ESXI 映射LUN 不大于 esxi usb映射_字段_09

3.1 查看映射

我们可以使用 _mapping 后缀来查看Elasticsearch中的映射。

ESXI 映射LUN 不大于 esxi usb映射_ESXI 映射LUN 不大于_10


结果:

ESXI 映射LUN 不大于 esxi usb映射_字段_11

3.2 自定义字段映射

ESXI 映射LUN 不大于 esxi usb映射_数组_12


string 类型的字段,默认的,考虑到包含全文本,它们的值在索引前要经过分析器分析,并且在全文搜索此字段前要把查询 语句做分析处理。

对于 string 字段,两个最重要的映射参数是 index 和 analyer 。

3.2.1 index

index 参数控制字符串以何种方式被索引。它包含以下三个值当中的一个:

ESXI 映射LUN 不大于 esxi usb映射_Elastic_13


string 类型字段默认值是 analyzed 。如果我们想映射字段为确切值,我们需要设置它为 not_analyzed :

ESXI 映射LUN 不大于 esxi usb映射_字段_14


其他简单类型—— long 、 double 、 date 等等——也接受 index 参数,但相应的值只能是 no 和 not_analyzed ,它们 的值不能被分析。

3.2.2 分析

对于 analyzed 类型的字符串字段,使用 analyzer 参数来指定哪一种分析器将在搜索和索引的时候使用。默认的, Elasticsearch使用 standard 分析器,但是你可以通过指定一个内建的分析器来更改它,例 如 whitespace 、 simple 或 english 。

ESXI 映射LUN 不大于 esxi usb映射_Elastic_15

3.3 更新映射

**你可以向已有映射中增加字段,但你不能修改它。如果一个字段在映射中已经存在,这可能意味着那个字段的数据已 经被索引。如果你改变了字段映射,那已经被索引的数据将错误并且不能被正确的搜索到。
**
我们可以更新一个映射来增加一个新字段,但是不能把已有字段的类型那个从 analyzed 改到 not_analyzed

为了演示两个指定的映射方法,让我们首先删除索引 gb :

ESXI 映射LUN 不大于 esxi usb映射_ESXI 映射LUN 不大于_16


然后创建一个新索引,指定 tweet 字段的分析器为 english :

ESXI 映射LUN 不大于 esxi usb映射_数组_17


再后来,我们决定在 tweet 的映射中增加一个新的 not_analyzed 类型的文本字段,叫做 tag ,使用 _mapping 后缀:

ESXI 映射LUN 不大于 esxi usb映射_数组_18


注意到我们不再需要列出所有的已经存在的字段,因为我们没法修改他们。我们的新字段已经被合并至存在的那个映射中。

3.4 测试映射

你可以通过名字使用 analyze API测试字符串字段的映射。对比这两个请求的输出:

ESXI 映射LUN 不大于 esxi usb映射_Elastic_19


tweet 字段产生两个词, “black” 和 “cat” , tag 字段产生单独的一个词 “Black-cats” 。换言之,我们的映射工作正常。

4. 复合核心字段类型

除了之前提到的简单的标量类型,JSON还有 null 值,数组和对象,所有这些Elasticsearch都支持:

4.1 多值字段

我们想让 tag 字段包含多个字段,。我们可以索引一个标签数组来代替单一字符串:

ESXI 映射LUN 不大于 esxi usb映射_字段_20


对于数组不需要特殊的映射。任何一个字段可以包含零个、一个或多个值,同样对于全文字段将被分析并产生多个词。

言外之意,这意味着数组中所有值必须为同一类型。你不能把日期和字符窜混合。如果你创建一个新字段,这个字段索引了 一个数组,Elasticsearch将使用第一个值的类型来确定这个新字段的类型。

当你从Elasticsearch中取回一个文档,任何一个数组的顺序和你索引它们的顺序一致。你取回的 _source 字段的顺序同样与 索引它们的顺序相同。

然而,数组是做为多值字段被索引的,它们没有顺序。在搜索阶段你不能指定“第一个值”或者“最后一个值”。倒不如把数组当 作一个值集合(gag of values)

4.2 空字段

当然数组可以是空的。这等价于有零个值。事实上,Lucene没法存放 null 值,所以一个 null 值的字段被认为是空字段。

ESXI 映射LUN 不大于 esxi usb映射_Elastic_21

4.3 多层对象

我们需要讨论的最后一个自然JSON数据类型是对象(object)

内部对象(inner objects)经常用于嵌入一个实体或对象里的另一个地方。例如,做在 tweet 文档中 user_name 和 user_id 的替 代,我们可以这样写:

ESXI 映射LUN 不大于 esxi usb映射_字段_22

4.3.1 内部对象的映射

Elasticsearch 会动态的检测新对象的字段,并且映射它们为 object 类型,将每个字段加到 properties 字段下

ESXI 映射LUN 不大于 esxi usb映射_字段_23