当前位置:首页 > ES > 正文内容

elasticsearch中mapping全解实战

phpmianshi1年前 (2019-07-24)ES24

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"
          }
        }
      }
    }
  }
}


版权声明:本文由PHP面试资料网发布,如需转载请注明出处。
分享给朋友:

相关文章

es中单机部署状态为Yellow解决办法

es中单机部署状态为Yellow解决办法

背景单机版的 ES 状态为 Yellow,在 Kibana 的管理界面看到的 index 的状态也是 Yellow这个问题在于单机版的 ES,是没有备份的,没有副本,设置 index 副本的数量为 0...

logstash增量同步mysql到es配置详解

配置详解input {   jdbc {     # mysql相关jdbc配置   ...

elasticsearch中动态模板全解实战

动态模板在我们最开始使用ES的时候,可能还不太了解mapping,也没有添加过mapping为什么我们还是能够正常的添加文档。那是因为ES可以动态映射,添加文档的时候遇到没有的字段,可以动态的添加到m...

elasticsearch中SearchApi的详解

搜索流程当一个搜索请求被发送到某个节点时,这个节点就变成了协调节点。 这个节点的任务是广播查询请求到所有相关分片并将它们的响应整合成全局排序后的结果集合,这个结果集合会返回给客户端。多索引搜...

logstash中同步mysql到elastic常见问题总结

1. mysql查询字段中有 type字段问题原因select语句中查到了type, 但es中会默认有一个type, 这使得两个type冲突.会导致同步失败,且没有报错GET my_inde...

elasticsearch中重新索引数据

概念虽然你可以给索引添加新的类型,或给类型添加新的字段,但是你不能添加新的分析器或修改已有字段。假如你这样做,已被索引的数据会变得不正确而你的搜索也不会正常工作。 修改在已存在的数据最简单的...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。