ElasticSearch之Mapping介绍

我们在之前的文章中提到ElasticSearch有三个重要的部分,Analysis,Query SQL以及Mapping。本文就来详细介绍这其中的Mapping。

我们知道假如我们需要解析一个数据的时候,比如“2018-10-01”,我们需要知道这是一个什么类型的数据,比如说这是一个时间数据,那么就可以解析成2018年10月1号,假如它只是一个字符串,那只是一系列字符。所以ElasticSearch是需要知道每个数据域的类型的,而这个类型就是包含在mapping中。

支持的类型

总得来说ElasticSearch支持以下这些简单的类型:

  • 字符串:string
  • 数字:byte,short,integer以及long
  • 浮点:float,double
  • 布尔变量: boolean
  • 日期: date

假如没有指定类型,那么ElasticSearch会使用动态mapping来猜测数据的类型,它的基本规则如下:

  • 如果是true或者false,就会认为是boolean型。
  • 如果是数字比如123,则会认为是long。
  • 如果是浮点数比如123.45,则会认为是double。
  • 如果是有效的日期字符串,比如2018-10-01,则会认为是date。
  • 如果是字符串比如 test result, 则会认为是string。

这里需要注意的是,假如你是一个数字字符串,比如”234”,默认它会被认为是一个string,除非这个域之前已经被解析成了long,它才会尝试把这个字符串转换成long,假如转换失败也会发出相应的exception。

Mapping的查看

你可以使用下面的命令来查看对应的mapping。这里就是查看index gb下面的tweet类型的mapping。

它的输出如下所示,我们可以看到各个域的类型。

自定义域的mapping

很多时候我们希望能够自定义域的mapping,比如对一个字符串域的处理,究竟是把它处理成long呢,还是字符,还是integer,这个是可以自定义的。你可以设置每个域的type的值来实现这个效果,如下所示:

即使对于同一个类型,比如说string类型,其实它也有很多有趣的设置。默认来说,string类型会认为是一个全文本看,在index之前会传递到analyzer中,然后在搜索之前也会把搜索的内容通过analyzer进行分析。而这个流程也是可以自定义的,这里有两个关键的设置,一个是index,另外一个是analyzer。

Index是用来决定string类型如何进行index,也就是说index之前需要如何处理,主要有以下三个值:

  • Analyzed:表示index之前也进行analyze。这个也是默认值,就是我们上面提到的流程。
  • Not_analyzed: 就是需要对这个域进行index,但是不要进行解析。
  • No:不进行index,所以这个域就彻底不能被搜索到了。

它的设置方法如下:

假如你设置的analyzed,也就是默认值,你还可以设置如何来进行analyze,这个是通过analyzer属性来决定的,默认使用standard analyzer,也可以使用别的比如whitespace,simple,english等等。具体可以参见之前的《ElasticSearch之Analysis介绍》。

你可以在创建index的时候指定mapping的属性,也可以再后面再加一些新的mapping,但是对于已经存在的你不能改变,因为这样的改变会导致已经index的数据出问题,你如果实在需要改变,可能需要通过先删除再创建的方法来实现了。

复杂的域类型

多值的域

这个有点类似数组,就是一个tag域中不止一个tag,这种情况下需要数组中的所有值都是同样的数据类型,也就是说你不能混合不同的类型。ElasticSearch会使用第一个元素的类型来决定整个域的类型。

空域

这里就是我们常说的null,或者空数组[]等等,其实对Lucene来说,这些域其实没有什么意义,就是和空的是一样的 ,他们其实不会被index。

多级的object

这个其实就类似别的语言中的hash,dictionary等等。比如说下面这个object:

ElasticSearch会自动detect到这种类型,并且把它设为object的类型,然后每一个独立的域再标致类型,对于内部域会列在properties中

这个时候你可能会问,内部的object是怎样进行index的,其实Lucene并没有内部object的概念,它只是一系列的key-value对,所以对于内部object其实会处理成下面这样的格式:

其实这里还有一个更好玩的问题,就是假如内部object是一个数组怎么办,比如下面这样的:

它其实会处理成这样:

这个时候其实一些对应的关系就丢失了,比如35岁和Mary White之间就没有对应关系了。所以相对应的查询可能就不准确了,这个可以使用Correlated inner object来处理,我们后面再重点介绍这个方法。

总结

至此本文就初步介绍了ElasticSearch中的mapping相关的概念,欢迎大家共同讨论。

You may also like...

Leave a Reply

Your email address will not be published.