write down,forget

Multi Field Type 介绍及使用方法

<Category: Diving Into ElasticSearch> 查看评论

洋洋洒洒写了几千字,结果发布提交丢了,很郁闷。
捡起来重新写吧,尼玛。

翻译了一下multi-field,在线在这里http://www.elasticsearch.cn/guide/reference/mapping/-type.html
以后翻译的文章都贴到博客里面吧,省的藏得太深,大家都找不到。
博客里面会补充详细的使用方法。
下面是multi-field的介绍:


multi_field 多域类型允许你对同一个值以映射的方式定义成多个基本类型 core_types . 这个非常有用,比如,如果你定义一个 string 类型的字段,你需要这个字段的分词一会是 analyzed ,但是有时候又希望该字段是 not_analyzed 类型的,通过使用 multi_field 就可以很方便的解决这个问题. 下面来看个例子:

上面的例子,显示了我们是如何定义一个名为 name 的字段, 它的数据类型是 string 字符类型, 该字段映射了两次(实际物理上产生了2个索引字段),其中一个是以 name 的名称 定义为 analyzed 分词类型,另外一个定义成了名称为 untouched 的 not_analyzed 类型,即不分词处理.
字段访问

当使用 multi_field mapping定义之后, fields里面的和字段名称和外部的字段名称相同的字段定义会被当做该mult-field的默认字段(因为一个multi类型字段会被拆分成多个字段,所以,会有一个默认值),我们可以通过直接名称 name 或者使用 tweet.name 格式的方式来指定字段.

其它定义的不同名称的字段也可以通过使用特点的导航来指定(即使用“.”符合来分割),如: name.untouched, 或者还带上类型名称 tweet.name.untouched.
合并Merging

当使用更新mapping接口 put_mapping 的时候,一个基本类型(core type) mapping定义能够自动升级成 multi_field mapping定义. 这意味着旧的定义是普通的基本类型的mapping,通过保持默认字段一致(即定义的multi-field的默认字段定义保持为旧的mapping的定义),就能够升级为 multi_field 类型.

开始介绍下更具体的用法,一步一步的啊。
mapping的使用和分词的配置之前也介绍过,再重头来一遍吧。

这么个场景,之前在pinyin插件里面写的,拿过来:https://github.com/medcl/elasticsearch-analysis-pinyin

我们现在需要实现人名的搜索,可以除了通过中文,还可以通过拼音来进行搜索,怎么做呢?
“执行索引前,转换中文姓名,得到拼音,然后分别建两个字段,往里面写数据,不就可以了吗?”
土了吧,看我给你介绍新的玩法。
用multi-field和pinyin插件。
前提准备:插件安装什么的我就不说了,可以使用RTF,相关都配置做好了,直接可以用。
1.自定义分词,开始之前,需要先定义好分词,可以在配置文件里面定义,但是不灵活,定义完了之后,需要重启es,还一种方式就是动态的添加自定义分词,如下所示:

上面自定义了一个名为my_pinyin的tokenizer,和名为pinyin_analyzer的analyzer,值得注意的是,修改索引的setting,需要先close索引,修改完之后,open就好了。

2.创建好索引,设置好analyzer,我们再来定义Type的,Type名称就用folks吧,有一个name字段,用来存姓名就好了。

上面定义了一个folks的Type,有一个字段名称为name,该字段数据类型为string,对象类型为multi-field,正因为类型是multi-field,它有了一些额外的参数可以进行设置,即fields,fields里面设置衍生字段的属性,可以是多个,每个都可以分别设置analyzer,store等参数,和core类型无异,如上,定义了一个name,使用的是pinyin analyzer和一个primitive,使用的是keyword analyzer,当想通过拼音搜索的时候,就对第一个字段name进行搜索就行了,如果需要完整匹配中文姓名,则对primitive字段进行搜索就行了。

3.mapping定义好了之后,咱们再开始往里面建索引,很多童鞋都是边改边查,结果就是反复重建,很费劲,尤其数据量大了之后,重建一次开销太大了,所以之前的需求分析和mapping定义工作是多么的重要,必须仔细考虑清楚了之后才开始,你的需求是什么?你到底想怎么查询?查询条件都有那些?场景是什么?搞明白了之后再定义mapping结构,再建索引。
来看一下如何建索引吧,multi-field,是不是需要赋值多次呢?错,一次就行了,看下面的例子:

实不相瞒,华仔是我的偶像,索引的时候,你只需要扔过去一个字段,然后相关的pinyin什么的都自动建好了,当然,你可以定义更多其它的字段,满足各种查询,但是建索引的时候,就赋一次值就行了。

4.如何查询呢?

需要注意的是,查询的时候,如果是中文,需要先用urlencode进行转码,上面的条件都能查询到“刘德华”
拼音可能会重音,我现在要完全匹配,
对,通过“primitive”字段呗,查询的时候,使用字段“name.primitive”作为查询域就行了,如下:

ok,multi-field的介绍就到这里。

本文来自: Multi Field Type 介绍及使用方法