0
点赞
收藏
分享

微信扫一扫

elasticsearch中mapping全解实战


Mapping简介​​#​​

mapping 是用来定义文档及其字段的存储方式、索引方式的手段,例如利用​​mapping​​ 来定义以下内容:

  • 哪些字段需要被定义为全文检索类型
  • 哪些字段包含​​number​​、​​date、布尔、浮点​​类型等
  • 格式化时间格式
  • 自定义规则,用于控制动态添加字段的映射

 

自定义mapping

mapping中的字段类型一旦设置,禁止直接修改,因为 lucene实现的倒排索引生成后不允许修改,应该重新建立新的索引,然后做reindex操作。

 

但是可以新增字段,通过 dynamic 参数来控制字段的新增,这个参数的值如下:

  • true:默认值,表示允许选自动新增字段
  • false:不允许自动新增字段,但是文档可以正常写入,但无法对字段进行查询等操作
  • strict:严格模式,文档不能写入,报错

 

自定义mapping 的步骤:

  1. 写一条文档到es的临时索引中,获取es自动生成的mapping
  2. 修改第一步得到的mapping,自定义相关配置
  3. 使用第2步的mapping创建实际的索引

 

Mapping Type​​#​​

每个索引都拥有唯一的 ​​mapping type​​​,用来决定文档将如何被索引。​​mapping type​​由下面两部分组成

  • Meta-fields
    元字段用于自定义如何处理文档的相关元数据。 元字段的示例包括文档的_index,_type,_id和_source字段。
  • Fields or properties
    映射类型包含与文档相关的字段或属性的列表。

示例

创建index并设置mapping


PUT my_index {   "mappings": {     "dynamic": false,     "properties": {       "title": {         "type": "text"       },       "name": {         "type": "keyword"       },       "age": {         "type": "integer"       }     }   } }


查看mapping


{   "my_index" : {     "mappings" : {       "dynamic" : "false",       "properties" : {         "age" : {           "type" : "integer"         },         "name" : {           "type" : "keyword"         },         "title" : {           "type" : "text"         }       }     }   } }


写入数据


POST my_index/_doc/1 {   "title":"hello world",   "desc":"this is a desc" }


注意,这里在mapping设置中,”dynamic”: false,表示在写入文档时,如果写入字段不存在也不会报错。这里的desc字段就是不存在的字段

查看,可以通过 title字段查询到文档的内容,但是通过 desc 查询是搜不到的。


get my_index/_search {   "query":{     "match":{       "title":"hello"     }   } }


 

大家可以试着把 dynamic设置成 strict模式试试,在strict 模式下插入不存在的字段将会出现报错

 

copy_to参数

作用是将该字段的值复制到目标字段,实现类似_all的作用。不会出现在_source中,只能用来搜索。


PUT my_index {   "mappings": {     "properties": {       "first_name": {         "type": "text",         "copy_to": "full_name"       },       "last_name": {         "type": "text",         "copy_to": "full_name"       },       "full_name": {         "type": "text"       }     }   } }


full_name的内容就是从 first_name 和 last_name 中复制过来的

创建一个新的文档,文档只需要写first_name 和 last_name


PUT my_index/_doc/1 {   "first_name": "john",   "last_name": "smith" }


查询一下,查询包含关键字john smith的文档,必须同时包含两个关键字才返回


GET my_index/_search {   "query": {     "match": {       "full_name": {         "query": "john smith",         "operator": "and"       }     }   } }


 

index参数

index参数作用是控制当前字段是否被索引,默认为true,false表示不记录,即不可被搜索。当在es中存储了一些不想要被检索的字段如身份证、手机等,这是对于这些字段就可以使用index设置为false,这样有一定的安全性还可以节省空间

 

 

index_options参数

index_options的作用是用于控制倒排索引记录的内容,有如下四种配置:

  • docs:只记录doc id
  • freqs:记录doc id 和term frequencies
  • positions:记录doc id、 term frequencies和term position
  • offsets:记录doc id、 term frequencies、term position、character offsets

 

text类型的默认配置为positions,其他默认为docs。记录的内容越多,占据的空间越大。

 

 

null_value参数

这个参数的作用是当字段遇到null值的时候的处理策略,默认为null,即空值,此时es会忽略该值。可以通过这个参数设置某个字段的默认值。

字段类型

字符串类型:text、keyword(不会分词)

  • 数值类型:long、integer、short、byte、double、float、half_float
  • 日期类型:date
  • 布尔类型:boolean
  • 二进制类型:binary
  • 范围类型:integer_range、float_range、long_range、double_range、date_range
  • 数组类型:array
  • 对象类型:object
  • 嵌套类型:nested object
  • 地理位置数据类型:geo_point、geo_shape
  • 专用类型:ip(记录ip地址)、completion(实现自动补全)、token_count(记录分词数)、murmur3(记录字符串hash值)

针对同一字段支持多种字段类型可以更好地满足我们的搜索需求,例如一个​​string​​​类型的字段可以设置为​​text​​​来支持全文检索,与此同时也可以让这个字段拥有​​keyword​​​类型来做排序和聚合,另外我们也可以为字段单独配置分词方式,例如​​"analyzer": "ik_max_word"​

text 类型​​#​​

​text​​类型的字段用来做全文检索,例如邮件的主题、淘宝京东中商品的描述等。这种字段在被索引存储前先进行分词,存储的是分词后的结果,而不是完整的字段。​​text​​​字段不适合做排序和聚合。如果是一些结构化字段,分词后无意义的字段建议使用​​keyword​​类型,例如邮箱地址、主机名、商品标签等。

常有参数包含以下

  • analyzer:用来分词,包含索引存储阶段搜索阶段(其中查询阶段可以被search_analyzer参数覆盖),该参数默认设置为index的analyzer设置或者standard analyzer
  • index:是否可以被搜索到。默认是​​true​
  • fields:Multi-fields允许同一个字符串值同时被不同的方式索引,例如用不同的analyzer使一个field用来排序和聚类,另一个同样的string用来分析和全文检索。下面会做详细的说明
  • search_analyzer:这个字段用来指定搜索阶段时使用的分词器,默认使用​​analyzer​​的设置
  • search_quote_analyzer:搜索遇到短语时使用的分词器,默认使用​​search_analyzer​​的设置
     

 

keyword 类型​​#​​

  • ​keyword​​用于索引结构化内容(例如电子邮件地址,主机名,状态代码,邮政编码或标签)的字段,这些字段被拆分后不具有意义,所以在es中应索引完整的字段,而不是分词后的结果。
  • 通常用于过滤(例如在博客中根据发布状态来查询所有已发布文章),排序和聚合。​​keyword​​只能按照字段精确搜索,例如根据文章id查询文章详情。如果想根据本字段进行全文检索相关词汇,可以使用​​text​​类型。

日期检测

当 Elasticsearch 遇到一个新的字符串字段时,它会检测这个字段是否包含一个可识别的日期,比如 2014-01-01 。如果它看起来像一个日期,这个字段会被作为 date 类型添加,否则,它会被作为 string 类型添加。

日期检测可以通过在根对象上设置 date_detection 为 false 来关闭:

Elasticsearch 判断字符串为日期的规则可以通过 dynamic_date_formats 配置 来修改。

多字段特性

多字段特性(multi-fields),表示允许对同一字段采用不同的配置,比如分词。

常见例子是对人名实现拼音搜索,只需要在人名中新增一个字段pinyin即可。但是这种方式不是十分优雅,multi-fields可以在不改变整体结构的前提下,增加一个子字段:


put my_index {   "mappings":{     "properties":{       "first_name":{         "type":"text",         "fields":{           "pinyin":{             "type":"text"           }         }       }     }   } }


 

 

举报

相关推荐

0 条评论