elasticsearch中mapping全解实战

参考:https://www.phpmianshi.com/?id=168

Mapping简介#

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

  • 哪些字段需要被定义为全文检索类型

  • 哪些字段包含numberdate、布尔、浮点类型等

  • 格式化时间格式

  • 自定义规则,用于控制动态添加字段的映射

 

自定义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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值