Elastic Seach基础—映射(Mapping)

Elastic Search的映射(Mapping)用于在一个索引中把文档划分为具有逻辑关系的分组,类似于数据库的表结构,是一个不可或缺的一部分。

自动生成

ES的Mapping可以类似于MongoDB那样自动生成,例如我们首先插入一条数据。

PUT twitter/_doc/1
{
  "user_name""kimchy",
  "age":25,
}

此时,可以通过API查看mapping设置

GET /twitter/_mapping

{
    "twitter": {
        "mappings": {
            "properties": {
                "age": { "type""long"  },
                "user_name": { "type""text",   "fields": { "keyword": { "type""keyword",  "ignore_above"256 } }
                }
            }
        }
    }
}

手动生成

自动生成可以大大减少我们创建mapping的步骤,但很多时候我们需要更精细化的设置,可以在创建索引的时候设置mapping:

PUT /twitter
{
    "mappings": {
        "properties": {
            "age": { "type""long" },
            "user_name": { "type""keyword""ignore_above"256 }
        }
    }
}

也可以将创建索引和创建映射作为两步实现:

PUT /twitter

PUT /twitter/_mapping
{
  "properties": { "age": {"type""long" },
    "user_name": { "type""keyword""ignore_above"256 }
  }
}

修改映射

Elastic Search允许增加字段的索引,可以通过Put接口增加字段的映射设置:

PUT /twitter/_mapping
{
  "properties": {
    "tag": { "type""text" }
  }
}

另外,Elastic Search也允许对已有字段增加类型(下文的多字段)。

但是,Elastic Search不允许对索引修改映射,我们再次执行创建mapping语句的时候会报错,对于修改映射的需求,ES提供了_reindex的api,具体的方式是:

  1. 创建一个新索引
  2. 通过_reindex API将数据从老索引移动到新索引

POST /_reindex
{
    "source": { "index""twitter" },
    "dest": { "index""twitter2" }
}

具体方法可以参考官方文档: Reindex is coming!

简单类型

对于映射设置,最常用的就是设置其字段类型,例如:

"properties": {
    "age": { "type""long" },
    "user_name": { "type""keyword" }
}

对于简单类型,ES对于其分类如下:

多字段

对于字符串类型,可以把它定义成两种类型: text和keyword。

  • text:只匹配其部分信息,内容会被分词,如文章。不支持聚合
  • keyword:必须完整匹配的内容,如邮箱,身份证号,部分匹配会导致错误的结果。支持聚合

这两种类型都是比较常用的,但有的时候,对于一个字符串字段,我们可能希望他两种都支持,此时,可以利用其多字段特性

"properties": {
    "user_name": {
        "type""text",
        "fields": {
            "keyword": {
                "type""raw",
                "ignore_above"256
            }
        }

}

对于user_name这个字段,其类型是text,同时又定义了一个"raw"的keyword的关键字段,当需要完全匹配的时候,可以通过user_name.raw查询。

更多内容可以参考其官方文档:Field datatypes

复合类型

ES支持三种复合类型:

  1. Array 数组型    :    支持数组形式,不需要一个专有的字段数据类型
  2. Object 对象型:    object数据类型:表现形式其实就是单一的JSON对象
  3. Nested 嵌套型:    nested数据类型:表现形式是多个Object型组成的一个数组

Array 数组型

Elasticsearch中,没有特定的array类型。默认情况下,任何字段都可以包含0个或者更多值,但是,所有array中的值必须具有相同的数据类型,例如:

  • 字符串数组:["one", "two"]
  • 整数数组:[1,2]
  • 数组的数组:[1, [2, 3]],等价于[1,2,3]
  • 对象数组:[ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }]

数组可以包含null值,这些值可以由配置的null_value替换或完全跳过。一个空的array []被视为不存在的字段-无值的字段。

Array类型是直接支持的,不需要特殊映射,如long类型的数组,直接映射成long即可。

Object 对象型

JSON文档本质上是分层的:文档包含内部对象,内部对象本身还包含内部对象。

PUT /account/_doc/1

{
    "region""US",
    "manager": {
        "age"30,
        "name""John Smith"
        }
    }
}

在内部,这个文档被索引为一个简单的、扁平的键值对列表,如下所示:

{
  "region""US",
  "manager.age"30,
  "manager.name ""John Smith"
}

索引方法如下:

{
    "mappings": {
        "properties": {
            "region": { "type""keyword" },
            "manager": {
                "properties": {
                        "age": { "type""integer" },
                        "name": { "type""text" }
                 }
            }
        }
    }
}

基本上是一个嵌套的方式,还是比较直观的。

Nested 嵌套型

由于对象扁平化存储,导致有的时候,对象数组并非你期望的那样工作,例如如下对象:

{
  "group""fans",
  "user": [
    {
      "first""John",
      "last""Smith"
    },
    {
      "first""Alice",
      "last""White"
    }
  ]
}

在内部被转化成如下格式的文档:

{
  "group""fans",
  "user.first": [
    "alice",
    "john"
  ],
  "user.last": [
    "smith",
    "white"
  ]
}

user.firstuser.last 扁平化为多值字段,alice 和 white 的关联关系丢失了。导致这个文档错误地匹配对 alice 和 smith 的查询

如果想并且保持数组中每个对象的独立性,在ElasticSearch中应该将其映射为nested对象类型而不是默认的object类型。

{
  "mappings": {
    "properties": {
      "user": {
        "type""nested"
      }
    }
  }
}

映射参数

除了前面列举的type参数外,还有不少其它参数可以设置,具体可以参考官方文档:Mapping parameters

其中大部分是可以不需要特殊设置的,采用默认参数即可,这里列举一下一些可能会用到的属性:

enable

ElasticSearch默认会索引所有字段,但是,有的信息是只需要存储,并不需要索引的。例如,一些链接url,往往只会用来读取,并不会作为搜索字段。在这些字段上建索引就会有无谓的性能浪费。

此时,我们可以设置enable属性为false,此时 Elasticsearch 完全跳过字段内容的分析,从而提高性能。

{
  "mappings": {
    "properties": {
      "url": {
        "type""object",
        "enabled"false
      }
    }
  }
}

需要注意的是,它只能使用在类型为object的字段上。设置为object并不影响任何功能,并且能存储任何类型,本身也能简化我们的mapping。

index

index的用法和enable非常相似,设置为index为false的字段不参与索引,但它是设置在非object类型上的。

至于它们有没有进一步的区别,官方也语焉不详,实际使用感觉没有啥太大区别,等有进一步结论后再完善本文。

analyzer

分析器用于设置字段的分词方法,它是ElasticSearch经常使用到的高级设置,具体内容在下一篇博文中介绍。

映射相关接口

关于映射更多接口,可以参考官方文档:Put mapping API

猜你喜欢

转载自www.cnblogs.com/TianFang/p/12945202.html