(八)类型映射详解

2018-12-22  本文已影响21人  LuoHaiPeng

前言

通过前面章节的学习,我们已经可以让elasticsearch对中文分词有比较好的效果了,就是使用IK分词器,但我们也知道,elasticsearch的默认分词器是standard分词器,那如何把standard分词器切换到IK分词器呢?
我们在讲解elasticsearch的重要概念的时候我们提到了一个概念:type(类型),为了更好的理解该概念,我们还拿了关系型数据库的表来跟type对比,因为他们不管是思想上还是概念上都是很相似的。
在使用关系型数据库时,我们是必须事先确定好数据表结构(schema),给该表中的每个字段规定其存储的数据类型和数据长度,是否能为空等等的约束,确定好后才能创建该表。但是大家回想之前我们在学RESTful API的时候,我们很简单的就完成了一个文档的新增操作了PUT /store/employee/1,并没有事先规定好类似关系型数据库表的约束,那么既然elasticsearch中的type跟表很相似,为什么我们新增一个文档的时候,就可以直接就录入文档呢?其实并不是没有事先规定约束的,我们当时还补充了录入这个文档的执行过程:先查找名字叫store的索引(index),如果没有,则创建该索引。然后查找名字叫employee的文档类型(type),如果没有,则创建该文档类型。最后查找id为1的员工,如果没有则相当于新建一个员工文档,并设置员工id为1,如果有,则相当于更新员工id为1的文档数据。这里的文档字段类型由elasticsearch帮我们完成自动匹配,当然我们也可以自定义文档的各个字段内容的数据类型和其他的一些约束。当时我们是这样说的,所以,并不是没有规定好约束,而是如果我们没有指定它的约束的话,elasticsearch就自动为我们创建好约束了。
在elasticsearch中,这些约束有个专业术语,叫做mapping(映射),类似关系型数据库的schema。那这样我们就明白了我们想要使用IK分词器来给我们的中文文档分词,就需要自己来给类型的字段指定映射,这些映射应该包含字段的数据类型、数据长度、使用分词器等等的约束。那接下来我们来学习一下elasticsearch的类型映射。

类型映射详解

查看文档类型映射

我们可以使用elasticsearch查看类型的API来查看指定文档的类型:
GET /索引名/_mapping/类型名

文档类型
通过该API得出的结果,我们可以得到以下的信息:索引、映射、类型、字段,在字段下,又有各种给该字段做约束的信息,所有的信息组合起来,就是我们所说的类型映射了(mapping)。employee的这些类型映射我们之前并没有给它设置,是elasticsearch自动判断我们的数据类型,并给这些数据类型设置默认的映射,那这各个字段分别代表什么意思呢?这就是我们接下来要学习的内容了。

字段数据类型

我们先来看看elasticsearch对文档的数据做了哪些类型的区分:

约束条件

元数据类型

每一个文档都有与之关联的元数据,元数据字段是为了保证系统正常运行内置字段,比如_index表示索引字段,_type表示类型,_id表示文档主键,这些字段都是以下划线开始的,除了这些元数据之外,还有两个很重要的元数据,它们是_all和_source,这两个元数据字段可以在我们创建类型映射的时候,指定约束条件,我们接着来看看:

{
    "yourtype":{
        "_source":{
            "enabled":false
        },
        "properties": {
            ... 
        }
    }
}

如果只想存储某几个字段的原始值到elasticsearch,可以通过incudes参数来设置,在mapping中的设置如下:

{
    "yourtype":{
        "_source":{
            "includes":["field1","field2"]
        },
        "properties": {
            ... 
        }
    }
}

同样,可以通过excludes参数排除某些字段:

{
    "yourtype":{
        "_source":{
            "excludes":["field1","field2"]
        },
        "properties": {
            ... 
        }
    }
}
{
   "yourtype": {
      "_all": {
         "enabled": true
      },
      "properties": {
            ... 
      }
   }
}

也可以通过在字段中指定某个字段是否包含在_all中:

{
   "yourtype": {
      "properties": {
         "field1": {
             "type": "string",
             "include_in_all": false
          },
          "field2": {
             "type": "string",
             "include_in_all": true
          }
      }
   }
}

最后,我们可以通过一张分析图来看看_all和_source在elasticsearch中起到的作用:


_source、_all图解

那到现在,我们已经把类型映射的数据类型、约束条件和元数据指定都了解了,接下来我们就可以对之前创建的employee类型指定约束条件了。

创建类型映射(mapping)

自定义employee类型映射

那接下来我们就要给employee类型做映射了,但是由于之前employee已经有一个elasticsearch创建的默认映射,而elasticsearch没有提供类似修改类型映射的功能,所以我们只能先把整个index删除掉,然后在新建一个index,并且在添加文档前做好employee类型映射。
注意:一般来说index是不能随便删除的,如果真的需要删除,那就要先备份数据,因为我们现在的数据都是测试数据,所以就不备份了,后面我们再来讲讲elasticsearch的数据备份操作
1、删除index
先把原先的store索引删除掉,使用以下DSL语法:
DELETE http://ip:port/my_index

删除索引
看到acknowledged为true,说明删除成功!
2、创建index
重新创建store索引,使用以下DSL语法:
PUT http://ip:port/my_index
创建索引
看到上图右边的窗口打印信息说明索引创建成功!
3、创建类型映射
创建employee类型映射,使用以下DSL语法:
PUT http://ip:port/my_index/my_type/_mapping
{
    "my_type": {
        "properties": {
            "my_field1": {
                "type": "text",
                "index":"true",
                "analyzer":"ik_max_word",
                "search_analyzer":"ik_max_word"
            },
            "my_field2": {
                ...
            },
            ...
        }
    }

}

语法解析:对my_index这个索引中的my_type文档类型创建一个自定义mapping映射,properties块就是my_type文档类型的字段。其中以my_field1这个字段举例,该字段的数据类型为“text”,index为需要分词,索引使用的分词组件为IK分词器,并且是最大分词,搜索同样使用IK分词器,并且是最大分词,其他没有指定的约束,使用默认的值。

创建映射
看到acknowledged为true的答应信息说明我们的employee文档类型约束已经创建好了,我给该文档类型3个字段做了约束,分别是name、age和about,其中name和about都是是text数据类型,需要分词,索引和搜索都使用ik_max_word分词,age是integer数据类型,不需要分词。
我们再使用查看类型映射的API测试一下,看看刚刚创建的类型映射是否生效:
查看类型映射
那通过我们上述的请求发现,我们的employee类型映射已经生效了,已经不是之前那个elasticsearch给我们创建的默认映射了。

添加文档

接下来我们在新的employee类型映射下添加文档:


新增文档

我从新添加了一份id为1的employee文档,但是我这份文档有4个字段,name、age、about和intersect,其中name、age和about是做了映射的,intersect没有做映射,那么elasticsearch就会自动判断intersect字段的数据类型,并且给他设置一些默认的约束。我们可以再来查看一下employee的类型映射有没有发生什么变化:


查看类型映射
通过上述查看employee类型映射我们发现,它此时多了intersect字段的映射,而且约束条件都是默认的,说明如果我们添加的文档某些字段没有事先做映射,那么elasticsearch会为我们这些字段创建映射。

搜索

根据我们前面章节的学习,我们知道在添加文档的时候,首先需要对文档进行索引,索引的第一个环节就是对文档分词,而我们刚刚已经在类型映射中,指定了文档分词的组件使用IK中文分词了,并且重新添加了文档,那这样的话,现在索引库中保存的词元就不再是一个一个的中文字符了,而是有语义的中文词语,最后我们来搜索效果。
先来看看搜索一个没有意义的字符:


搜索“中”

我们可以看到,搜索“中”字符已经不会出来结果了,因为“中”字符单独存在没有什么意义,那接下来我们搜索“中国”看看:


搜索“中国”
搜索“中国”能出来结果,并且我们通过高亮显示可以知道,它是匹配到“中国”这个词元的。
那到现在,我们就通过这个章节的学习,了解了elasticsearch的数据类型、字段约束条件和类型映射这几个知识点了,并且通过自定义的类型映射来实现了中文语义搜索。
上一篇 下一篇

猜你喜欢

热点阅读