ElasticSearch中的映射

         这里讲的ElasticSearch中的映射(schema mapping),是定义存储和索引的文档类型和字段的过程。这里记住映射是一个动态过程。索引中的每个文档都有一个类型,每种类型都有他本身的映射。映射起到定义文档字段的数据类型的功能,这一功能实际上是经过配置来定义字段类型和该类型关联的元数据的关系来实现的。json

映射类型

每一个索引都有一个或多个映射类型,他的做用是在一个索引中将数据划分为不一样的逻辑组。每一个映射类型都由元字段和字段组成。数组

1.元字段

元字段的做用是用来表示如何处理文档的元数据。常见的元字段有 _index,_type,_id,_source。 每一个文档都有与之关联的元数据,元字段是保证系统正常运转的内置字段。app

2.字段(或属性)

字段(或属性)的做用是标识数据的类型。每一个映射类型都包含与类型相关的字段或者属性列表。这里注意若是是在同一个索引中的不一样映射类型的相同字段都具备相同的数据类型,意思是指在同一索引范围中,只要映射字段相同,那么他就具备相同的映射类型。编码

字段数据类型

ElasticSearch中的字段数据类型包括基本的字符串,日期,长整型long,双精度double,布尔型boolean,相似JSON的对象,IP,地理点和地理形状(之后会对不一样的类型作详细解释)。ElasticSearch能够显式或者动态的设置映射,ElasticSearch的映射能够不事先定义,依靠动态映射,依靠新的索引文档,新的类型和字段名能够自动添加。而新的类型映射又能够添加到顶级映射类型或者映射类型内部的对象和嵌入字段。url

映射类型在一个索引中是惟一的。也就是在同一个索引的不一样类型中,相同的映射名称同样,那么他们就具备相同的类型。3d

1. 核心数据类型

  • 字符串数据类型

字符串数据类型能够分为全文本和关键词,同一字段又能够同时设置全文本和关键字。全文本很是适合基于文本的相关性搜索。rest

全文本的字符串数据类型能够分词,在索引执行以前经过分词器将文本转化为单词表,这个操做就是ElasticSearch能在全文本中搜索单词的原理。这里注意全文本的字符串数据类型不用于排序且不多用于聚合。code

关键词的字符串数据类型一般用来过滤,排序和聚合。而且不参与分词。cdn

  • 数字
  • 日期类型:注意json没有日期类型,因此只能是字符串,表明时间毫秒数的长整型,或者整型。可使用双竖线作多日期格式匹配。
  • boolean类型
  • base64编码的二进制值。不以默认方式存储且不能被搜索。

2. 复杂数据类型

  • 数组

ElasticSearch没有特定的数组类型,可是每一个字段默承认以包含一个或者多个相同数据类型的值。对象

  • 对象类型

这里指的对象类型采用的是json的自然分层特性。json文档内部能够包含对象。

  • 嵌套数据类型

3. 地理数据类型

这里的地理数据类型说的是经纬度。从经纬度扩展一下几个方面:

  • 查找必定地理范围内的数据
  • 聚合距离中心点必定距离的文档
  • 按照距离中心点的远近进行排序
  • 整合地理数据到文档的相关性评分中

地理数据类型又分为:

  • 地理点
  • 地理形状

3. 专门数据类型

  • IP
  • 单词计数器:token_count

映射参数

用于字段映射的参数。ElasticSearch中有大量的映射参数,这些参数的默认值都是最合适广泛场景的,可是若是想精通调优,须要理解这些映射参数。下面这些是选取的几个典型映射参数。

1.analyzer

字符串在索引和查询时,都是被分析为一个个索引词。经过合理的配置索引器能够大大提升在索引查询时的效率。

2.boost

对字段进行加权。默认值为1,若是设置了值则是所设置值的倍数。这里注意在数据索引时最好不要加权。由于除非从新索引全部文档,否则加权值不会变。

3.coerce

强制类型转换。若是值为false,在索引到不匹配类型的文档时就会丢弃

4.facat

facat表明多字段,ElasticSearch容许你在一个字段上设定两种类型。假如你想在同一个字段上进行两种分析,一种用于搜索,一种用于排序。或一个通过特定语言分析器来分析,而另外一个只通过空白字符分析。那么可使用多字段功能。该功能能够容许用户只定义一个字段类型就同时赋予该字段两种类型的类型。以下所示:

“name”:{ “type”:”string”, “property”:{ “facat”:{“type”:”string”,”index”:”not_anayzed"} } }

这样就定义了两个字段,一个叫name,一个叫name.property,ElasticSearch会把name字段中的值复制到name.property字段中。

5.copy_to

ElasticSearch可使用这个字段来建立自定义的_all字段。也就是说能够用多个字段来合成一个字段,把这个合成的字段当作单个字段来查询。

6.doc_valus

倒排索引的列式存储。这种结构很适合聚合,排序,脚本操做。

动态索引

ElasticSearch能够在事先不设置索引结构的状况下,在文档直接插入到索引中时,系统会根据文档自动进行索引结构的动态映射。这样作极大地简化了索引的操做。

能够根据目的来指定动态映射生成的规则:

  • ElasticSearch中有个名为_default_的默认映射,这个默认映射至关于建立新映射类型的基础映射。
  • 动态字段映射。
  • 动态模板:也就是根据事先定义好的自定义规则来配置动态添加字段的映射。

默认状况下,在文档中发现新的字段的时候,ElasticSearch会自动根据一系列简单的规则将新字段添加到类型映射中。这些简单的规则中,有些能解析形如日期的字符串,有些能解析数字。其实ElasticSearch底层是经过定义文档的JSON来猜想文档结构和数据类型的,好比字符串是被引号包围,布尔值使用特定的字符,数值则是一些数字类型。很明显,这些简单的规则有效并且易于理解。

那么有没有更加灵活的文档类型探测呢?好比被引号包围的数字类型能不能被检测为数值类型呢,答案是确定的。ELasticsearch有种机制叫数值自动检测,相关联的设置为numeric_detection,该选项是默认关闭的,可使用响应的put请求来打开该选项。若是该选项打开后,在索引数据时若是被引号包围的数据为数组类型,好比float型数据,那么在索引完后,使用get方法来请求索引的_mapping_数据,你会发现刚才的数值类型的字段的type为double了,固然若是索引的数值不是float,而是long类型数据,那么_mapping中的类型也会变成long。

映射是如何xxx的

首先找到映射的入口。因为都是从rest的接口新增的映射,因此从rest包中入手确定没有错。因为rest包中的类很少,查看后知道了映射相关的类在indices包中。由于在映射都是依附在index上的,因此放到了indices包下。以下图所示:

新增映射的入口

接下来找到入口,就分析是如何构造映射的。

  • 首先经过url中的index字段构造一个初始的PutMappingRequest
  • 而后给该PutMappingRequest构造各类request中携带的参数
    • type:映射相关元数据
    • source:映射相关元数据
    • update_all_types:是否跨多个类型的映射字段都更新
    • timeout:超时
    • master_timeout:若是在没有发现master或者断开与master链接状况下的超时值
    • expand_wildcards:索引配置相关,启用的扩展通配符
    • ignore_unavailable:索引配置相关,snapshot,restore和index_settings操做使用此设置。
    • allow_no_indices:索引配置相关,
  • 最后经过NodeClient(实现了IndicesAdminClient接口)中的putMapping方法,将上一步构造好的action传给ElasticSearch的client。

下图显示了实际执行映射操做的地方是NodeClientexecute方法

d

上面提到的PutMappingRequest初始化的参数以下图所示,可看到咱们put的数据都在source中:

而后会从actions中找到putmapping的action,action的类型为TransportAction。而该action的实际执行方法execute,该方法是当transport操做调用致使产生一个新的关联任务时,实际使用的方法。

咱们能够看到该方法使用默认好的actionName'indices:admin/mapping/put'和构造好的putMappingRequest注册了一个task。而后分别在ActionListener中设置了成功和失败的回调方法。

因为我是单节点运行的ElasticSearch,因此在实际执行任务的类是TransportMasterNodeAction,这个类是须要在主节点上执行的操做的基类。在该类的doStart方法中,经过类TransportPutMappingAction和参数taskreqeust最众到达实际的方法metaDataMappingService.putMapping中,以下图所示;

至此前面的任务调度工做就都作完了,之后就是metaDataMappingService.PutMappingExecutor的工做了。

相关文章
相关标签/搜索