zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Django框架11 /form组件、modelForm组件
    Django框架10 /sweetalert插件、django事务和锁、中间件、django请求生命周期
    Django框架09 /ajax、crsf、settings导入
    Django框架08 /聚合查询、分组、F/Q查询、原生sql相关
    (转)JVM中的OopMap(zz)
    mysql limit 性能问题分析
    NoClassDefFoundError && ClassNotFoundException
    定点分析: MySQL InnoDB是如何保证系统异常断电情况下的数据可靠性?
    java GC 算法
    IDEA在线注册方法
  • 原文地址:https://www.cnblogs.com/TianFang/p/12945202.html
Copyright © 2011-2022 走看看