Elasticsearch 常用数据类型和映射

文章目录

  • Elasticsearch 数据类型
    • 常见类型
    • 对象类型
    • 结构化数据类型
    • 文本搜索类型
    • 聚合数据类型
    • 文档排名类型
    • 空间数据类型
    • 数组
  • 映射
    • 动态字段映射
    • 动态模板映射
  • 显式映射
    • 创建索引时直接映射字段
    • 更新映射 API
      • 路径参数
      • 查询参数
      • 请求正文
    • 示例:添加新的映射字段
    • 示例:为object类型字段添加新字段
    • 示例:修改已有的映射字段
    • 获取映射API
      • 路径参数
      • 查询参数
  • 映射参数
    • dynamic 是否动态映射
      • 示例
      • dynamic 可接收的参数
    • coerce 强制转换(数字类型)
      • 示例
        • 在索引级别使用 index.mapping.coerce 设置
    • analyzer 指定文本分析器
    • search_analyzer
    • copy_to 复制字段
      • 示例
    • enabled 禁用对象字段
    • format 日期格式化
    • ignore_above、ignore_malformed
    • fields
    • null_value 空值
    • store

Elasticsearch 数据类型

常见类型

  • binary:接受二进制值作为 Base64编码字符串。该字段默认不存储且不可搜索,且不得嵌入换行符\n。
  • boolean:布尔值,true 或 false
  • keyword 关键字类型
    • keyword,用于结构化内容,例如 ID、电子邮件地址、主机名、状态代码、邮政编码或标签。
    • constant_keyword 静态常量关键字类型。
    • wildcard 通配符关键字类型。
  • 数字类型
    • 整数 integer、long、short、byte
    • 浮点型 float、double等,浮点型可能损失精度
    • scaled_float 我们要存的值。其对应一个附加参数 scaling_factor(缩放因子)
      • 比如 scaled_float = 1.23,scaling_factor = 10,那么在elastic中存储的值为 12(按整数存储,不损失精度),我们之后再取出来,值就变成了1.2。
      • 如果要完整存储,那么 scaling_factor 就应该设置为100
  • 日期类型
    • type 为 date
    • “2015-01-01” 或 “2015/01/01 12:10:30”
    • 毫秒数
    • 可以使用 format 参数 配置自定义格式(epoch_millis 毫秒数、yyyy-MM-dd HH:mm:ss.SSS 等符合java DateFormat的日期格式)
    • format可以同时使用多一个格式中间用 || 隔开 (如:yyyy-MM-dd || yyyy-MM-dd HH:mm:ss)
  • alias 别名类型
    • 别名类型同时需要设置 path 参数,参数的值为对应别名的字段。字段可能是个对象调用链(object1.object2.field)

对象类型

  • object 对象类型(表示该字段是一个对象类型)
  • flattened 平铺字段类型,将整个对象映射为单个字段。有助于防止映射爆炸。但只支持基本的查询。
  • nested 嵌套字段类型
    • 例如:
      {
      “first” : “John”,
      “last” : “Smith”
      },{
      “first” : “Alice”,
      “last” : “White”
      }
      当我们查询 first:alice,last:"White"时,将不会有结果
  • join 类型是在同一索引的文档中创建父/子关系的特殊字段。

结构化数据类型

  • 范围类型,范围字段类型表示上限和下限之间的连续值范围。例如,一个范围可以表示十月的任何日期或从 0 到 9 的任何整数。它们是使用运算符 gt或gte用于下限和lt或lte用于上限定义的。它们可用于查询,但对聚合的支持有限。

    • integer_range、float_range、long_range、double_range、date_range、ip_range
  • ip 字段类型(ip)存储IPv4或IPv6

  • version 版本字段类型

文本搜索类型

  • text字段类型
    • text,全文内容的字段类型,例如电子邮件正文或产品描述。它被索引之前会被文本分析器(分词器)进行拆分。text 字段最适合非结构化但可读的内容。
    • match_only_text,一种空间优化的变体,它禁用评分,并且在需要位置的查询上执行速度较慢。它最适合索引日志消息。

聚合数据类型

  • aggregate_metric_double
    预先聚合的指标值。
  • histogram
    直方图形式的预聚合数值。

文档排名类型

  • dense_vector
    记录浮点值的密集向量。
  • rank_feature
    记录数字特征以提高查询时的命中率。
  • rank_features
    记录数字特征以提高查询时的命中率。

空间数据类型

  • geo_point
    纬度和经度点。
  • geo_shape
    复杂的形状,例如多边形。
  • point
    任意笛卡尔点。
  • shape
    任意笛卡尔几何。

数组

在 Elasticsearch 中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值必须属于相同的字段类型

映射

映射是定义文档及其包含的字段如何存储和索引的过程

动态字段映射

默认情况下,当 Elasticsearch 检测到文档中的新字段时,它会默认将该字段动态添加到类型映射中。此功能由映射的参数 dynamic 来决定,这个我们后续来详细说明。
动态字段映射类型对应表

JSON 字段类型 “dynamic”:“true” “dynamic”:“runtime”
null 无对应字段 无对应字段
true/false boolean boolean
double float double
long long long
object object 无对应字段
array 取决于数组中第一个非null值 取决于数组中第一个非null值
string通过日期检测 date date
string通过数值检测 float或者long float或者long
string没有通过date检测或numeric检测 text有一个.keyword子字段 keyword

date_detection 禁用日期检测

{
 "mappings": {
  "date_detection": false
 }
}

dynamic_date_formats 自定义动态映射的日期格式

{
 "mappings": {
   "dynamic_date_formats": ["MM/dd/yyyy"] // 可配置多个格式
 }
}

numeric_detection false禁用或true启用数字检测(默认为禁用的,在某些应用中,数字会被映射成text)

{
 "mappings": {
   "numeric_detection": true
 }
}

动态模板映射

动态模板映射,是为了控制在默认动态字段映射规则之外映射数据。在进行索引映射的时候,通过各种条件去对应适配动态模板,但此方式也不能解决更精确的字段映射,所以此处我们就不展开说了。

显式映射

我们在日常开发使用中,我建议大家使用显式映射,以更精确的映射字段类型。更便于 elasticsearch 针对对应字段做更精确的索引分析等。

创建索引时直接映射字段

使用创建索引的API直接映射字段(关于创建索引API的说明,请查看 Elasticsearch REST API 索引管理 )

PUT /person

{
    "mappings": {
        "properties": {
            "age": { 
                "type": "integer"
            },  
            "birthday":  { 
                "type": "date",
                "format":"yyyy-MM-dd HH:mm:ss" 
            }, 
            "name":   { 
                "type": "keyword"  
            },
            "height": {
                "type": "float"
            },
            "id": {
                "type": "long"
            },
            "sex":{
                "type": "byte"
            }
        }
    }
}

如果咱们不显式定义映射,那么 birthday 和 name 都会被映射为 text 类型。

更新映射 API

PUT /<target>/_mapping

路径参数

  • target 索引名

查询参数

  • allow_no_indices
    (可选,布尔值)如果 为false,任何通配符表达式、索引别名或值目标仅丢失或关闭索引,请求将返回错误 。例如,如果请求索引以 foo*,bar* 开头,如果有索引,以foo开头但没有索引以bar开头,则请求定位会返回错误。 默认为true.

  • expand_wildcards
    (可选,字符串)通配符模式可以匹配的索引类型。支持逗号分隔值,例如open,hidden。默认为open.可选值为:

  • all
    匹配任何数据流或索引,包括隐藏的。

  • open
    匹配开放的、非隐藏的索引。也匹配任何非隐藏数据流。

  • closed
    匹配封闭的、非隐藏的索引。也匹配任何非隐藏数据流。数据流无法关闭。

  • hidden
    匹配隐藏的数据流和隐藏的索引。open必须与、 closed或两者 结合使用。

  • none
    不接受通配符模式。

  • ignore_unavailable
    (可选,布尔值)false,如果请求针对丢失或关闭的索引,则请求返回错误。默认为false.

  • local
    (可选,布尔值)true,则请求仅从本地节点检索信息。默认为false,这意味着信息是从主节点检索的。

  • master_timeout
    (可选,时间单位)等待连接到主节点的时间。如果在超时到期之前未收到响应,则请求失败并返回错误。默认为 30s.

请求正文

properties
(必填,映射对象)字段的映射。对于新字段,此映射可以包括:

  • 字段名称
  • 字段数据类型
  • 映射参数

示例:添加新的映射字段

PUT /person/_mapping
{
    "properties":{
        "weight": {
            "type": "float"
        }
    }
}

示例:为object类型字段添加新字段

PUT /person/_mapping
{
    "properties":{
        "child": {
            "properties": {
				"name": {
					"type": "keyword"
				}
			}
        }
    }
}

示例:修改已有的映射字段

注:此操作要谨慎操作,更改现有字段可能会使已编制索引的数据无效。必须要修改,修改之后需要重新索引。

如:把我们刚刚添加的新字段映射类型修改为 keyword

PUT /person/_mapping
{
    "properties":{
        "weight": {
            "type": "keyword"
        }
    }
}

修改之后,我们需要重新索引(请查看上一篇文章 Elasticsearch REST API 文档管理)

获取映射API

GET /_mapping

GET /<target>/_mapping

路径参数

  • target
    (可选,字符串)用于限制请求的数据流、索引和别名的逗号分隔列表。

查询参数

  • allow_no_indices
    (可选,布尔值)如果 为false,任何通配符表达式、索引别名或值目标仅丢失或关闭索引,请求将返回错误 。例如,如果请求索引以 foo*,bar* 开头,如果有索引,以foo开头但没有索引以bar开头,则请求定位会返回错误。 默认为true.

  • expand_wildcards
    (可选,字符串)通配符模式可以匹配的索引类型。支持逗号分隔值,例如open,hidden。默认为open.可选值为:

  • all
    匹配任何数据流或索引,包括隐藏的。

  • open
    匹配开放的、非隐藏的索引。也匹配任何非隐藏数据流。

  • closed
    匹配封闭的、非隐藏的索引。也匹配任何非隐藏数据流。数据流无法关闭。

  • hidden
    匹配隐藏的数据流和隐藏的索引。open必须与、 closed或两者 结合使用。

  • none
    不接受通配符模式。

  • ignore_unavailable
    (可选,布尔值)false,如果请求针对丢失或关闭的索引,则请求返回错误。默认为false.

  • local
    (可选,布尔值)true,则请求仅从本地节点检索信息。默认为false,这意味着信息是从主节点检索的。

  • master_timeout
    (可选,时间单位)等待连接到主节点的时间。如果在超时到期之前未收到响应,则请求失败并返回错误。默认为 30s.

示例:查询映射

GET /person/_mapping

示例:查询所有映射

GET /*/_mapping

GET /_all/_mapping

GET /_mapping

映射参数

dynamic 是否动态映射

作用于文档或文档的内部对象

示例

PUT /person
{
  "mappings": {
    "dynamic": false, 
    "properties": {
      "user": { 
        "properties": {
          "name": {
            "type": "text"
          },
          "car": {
            "dynamic": true, 
            "properties": {}
          }
        }
      }
    }
  }
}

该映射表示,我们的文档第一层的字段,只有user,新增的字段将不不会被索引或搜索,而user字段对象,car对象的字段可以动态新增并添加到映射。

dynamic 可接收的参数

  • true
    新字段添加到映射(默认)。
  • runtime
    新字段作为运行时字段 添加到映射中。这些字段没有索引,在_source在查询时加载。
  • false
    忽略新字段。这些字段不会被索引或搜索,但仍会出现在_source返回的命中字段中。这些字段不会添加到映射中,必须显式添加新字段。
  • strict
    如果检测到新字段,则会抛出异常并拒绝文档。

coerce 强制转换(数字类型)

如果设置为true(默认为true)elasticsearch 将会自动转换我们在创建文档时传入的值:

  • 将字符强制转换为数字
  • 如果映射类型为整型,但传入了浮点型,浮点数将会被截断

示例

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "number_one": {
        "type": "integer"
      },
      "number_two": {
        "type": "integer",
        "coerce": false
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "number_one": "10" 
}

PUT my-index-000001/_doc/2
{
  "number_two": "10" 
}

number_one 的 10 会被转换为整型,但 number_two 文档会报错无法新增。

在索引级别使用 index.mapping.coerce 设置
PUT my-index-000001
{
  "settings": {
    "index.mapping.coerce": false
  },
  "mappings": {
    "properties": {
      "number_one": {
        "type": "integer",
        "coerce": true
      },
      "number_two": {
        "type": "integer"
      }
    }
  }
}

使用索引的settings来设置index.mapping.coerce,禁用自动强制类型转换。

analyzer 指定文本分析器

指定的分析器用于索引和搜索分析

关于分析器的具体功能,我们将在后续文章中单独讲解。

search_analyzer

同 analyzer 只不过是其只指定 用于搜索的分析器。

注:一般情况下用于索引和搜索的分析器应该为同一个,所以只指定analyzer 即可。

copy_to 复制字段

copy_to 可以将多个字段的值复制到一个组字段中,然后可以将其作为单个字段进行查询。

示例

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "first_name": {
        "type": "text",
        "copy_to": "full_name" 
      },
      "last_name": {
        "type": "text",
        "copy_to": "full_name" 
      },
      "full_name": {
        "type": "text"
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "first_name": "John",
  "last_name": "Smith"
}

GET my-index-000001/_search
{
  "query": {
    "match": {
      "full_name": { 
        "query": "John Smith",
        "operator": "and"
      }
    }
  }
}

enabled 禁用对象字段

elasticsearch 默认情况下,会为我们添加的字段添加索引,如果我们只想存储字段而不对其建立索引。可以使用 enabled 参数

注:enabled 只能作用于 索引级别或文档中的object字段

PUT /index
{
	"mappings": {
		"enabled": true,
	   "properties": {
			"name": {
				"type":"keyword"
			},
			"car":{
				"type": "object",
				"enabled":false
			}
	    }
    }
}

format 日期格式化

日期格式化的格式遵循Java的日期格式化格式,如:yyyy-MM-dd HH:mm:ss.SSS。我们在文档管理的示例中已经添加过了。

ignore_above、ignore_malformed

ignore_above 数字类型,比如:20.表示字符串超过相应长度,将不被索引。
ignore_malformed 正常情况下,日期类型不正确或数字类型不正确,将忽略此字段,而且文档的其他字段会正常存储。如果设置为false,则如果出现日期类型不正确将会导致整个文档添加失败。

fields

为不同的目的以不同的方式索引同一个字段, string 字段可以映射为 text 用于全文搜索,也可以映射为 keyword 用于排序或聚合

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "city": {
        "type": "text",
        "fields": {
          "raw": { 
            "type":  "keyword"
          }
        }
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "city": "New York"
}

PUT my-index-000001/_doc/2
{
  "city": "York"
}

GET my-index-000001/_search
{
  "query": {
    "match": {
      "city": "york" 
    }
  },
  "sort": {
    "city.raw": "asc" 
  },
  "aggs": {
    "Cities": {
      "terms": {
        "field": "city.raw" 
      }
    }
  }
}

null_value 空值

null_value 将显式值替换null为指定值,以便对其进行索引和搜索。

PUT my-index-000001
{
  "mappings": {
    "properties": {
      "status_code": {
        "type":       "keyword",
        "null_value": "NULL" 
      }
    }
  }
}

此示例我们将null值映射为 “NULL” 字符串

store

是否将数据进行独立存储,默认为 false
原始的文本会存储在_source 里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source 里面提取出来的。当然你也可以独立的存储某个字段,只要设置"store": true 即可,获取独立存储的字段要比从_source 中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置。

你可能感兴趣的:(elasticsearch,数据类型,Mapping,分词器,平铺类型)