架构师系列-搜索引擎ElasticSearch(六)- 映射

映射配置

在创建索引时,可以预先定义字段的类型(映射类型)及相关属性。

数据库建表的时候,我们DDL依据一般都会指定每个字段的存储类型,例如:varchar、int、datetime等,目的很明确,就是更精确的存储数据,防止数据类型格式混乱,在Elasticsearch中也是这样,创建索引的时候一般也需要指定索引的字段类型,这种方式称为映射(Mapping)。

被动创建(动态映射)

此时字段和映射类型不需要事先定义,只需要存在文档的索引,当向此索引添加数据的时候当遇到不存在的映射字段,ES会根据数据内容自动添加映射字段定义。使用动态映射的时候,根据传递请求数据的不同会创建对应的数据类型。

禁止动态映射

一般生产环境下需要禁用动态映射,使用动态映射可能出现以下问题

  1. 造成集群元数据一直变更,导致不稳定;
  2. 可能造成数据类型与实际类型不一致;

禁用动态映射,动态mappingdynamic字段进行配置,可选值及含义如下

  • true:支持动态扩展,新增数据有新的字段属性时,自动添加对于的mapping,数据写入成功
  • false:不支持动态扩展,新增数据有新的字段属性时,直接忽略,数据写入成功
  • strict:不支持动态扩展,新增数据有新的字段时,报错,数据写入失败

主动创建(显示映射)

我们需要对字段除了数据结构定义更多的限制的时候,动态映射创建的内容很可能不符合我们的需求,所以可以使用PUT {index}/mapping来更新指定索引的映射内容。

映射类型

我们要创建映射必须还要知道映射类型,否则就会走默认的映射类型,下面我们看看常用的映射类型。

准备工作

bash 复制代码
# 创建一个索引
PUT mapping_demo

字符串类型

符串类型可以被设置为以下几种类型

text

当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型,text类型会被分词。设置text类型以后,字段内容会被分词,在生成倒排索引以前,字符串会被分析器分成一个一个词项,text类型的字段不用于排序,很少用于聚合

keyword

keyword类型不会被分词,常用于关键字搜索,比如姓名、email地址、主机名、状态码和标签等。如果字段需要进行过滤(比如查姓名是张三发布的博客)、排序、聚合,keyword类型的字段只能通过精确值搜索到,常常被用来过滤、排序和聚合。

两者区别

它们的区别在于text会对字段进行分词处理而keyword则不会进行分词。如果字段是text类型,存入的数据会先进行分词,然后将分完词的词组存入索引,而keyword则不会进行分词,直接存储,这样划分数据更加节省内存。

使用案例

先创建一个映射,name是keyword类型,描述是text类型的

bash 复制代码
PUT mapping_demo/_mapping
{
  "properties": {
    "name": {
        "type": "keyword"
     },
      "city": {
        "type": "text",
        "analyzer": "ik_smart"
     }
  }
}

# 插入数据
PUT mapping_demo/_doc/1
{
  "name":"北京小区",
  "city":"北京市昌平区回龙观街道"
}

# 对于keyword的name字段进行精确查询
GET mapping_demo/_search
{
  "query": {
    "term": {
      "name": "北京小区"
    }
  }
}

# 对于text的city进行模糊查询
GET mapping_demo/_search
{
  "query": {
    "term": {
      "city": "北京市"
    }
  }
}

数字类型

数字类型也是我们最常用的类型之一,下面我们看下数字类型的使用。

  • 在满足需求的情况下,优先使用范围小的字段,字段长度越小,索引和搜索的效率越高。

日期类型

JSON表示日期

JSON没有表达日期的数据类型,所以在ES里面日期只能是下面其中之一。

  • 格式化的日期字符串,比如:"2015-01-01" or "2015/01/01 12:10:30"
  • 用数字表示的从新纪元开始的毫秒数
  • 用数字表示的从新纪元开始的秒数(epoch_second)

ES如何处理日期

在ES的内部,时间会被转换为UTC时间(如果声明了时区)并使用从新纪元开始的毫秒数的长整形数字类型的进行存储,在日期字段上的查询,内部将会转换为使用长整形的毫秒进行范围查询,根据与字段关联的日期格式,聚合和存储字段的结果将转换回字符串。

默认日期格式

日期的格式可以被定制化的,如果没有声明日期的格式,它将会使用默认的格式。

"strict_date_optional_time||epoch_millis"

意味着它将会接收带时间戳的日期,它将遵守strict_date_optional_time限定的格式(yyyy-MM-dd'T'HH:mm:ss.SSSZ 或者 yyyy-MM-dd)或者毫秒数。

日期格式示例

javascript 复制代码
PUT mapping_demo/_mapping
{
  "properties": {
    "datetime": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
     }
  }
}
# 添加数据
PUT mapping_demo/_doc/2
{
  "name":"河北区",
  "city":"河北省小区",
  "datetime":"2022-02-21 11:35:42"
}

日期类型参数

布尔类型

boolean类型用于存储文档中的true/false

范围类型

范围类型字段中存储的内容就是一段范围,例如年龄30-55岁,日期在2020-12-28到2021-01-01之间等。

es中有六种范围类型:

  • integer_range
  • float_range
  • long_range
  • double_range
  • date_range
  • ip_range

使用实例

javascript 复制代码
PUT mapping_demo/_mapping
{
  "properties": {
    "age_range": {
        "type": "integer_range"
     }
  }
}

# 指定年龄范围,可以使用 gt、gte、lt、lte。
PUT mapping_demo/_doc/3
{
  "name":"张三",
  "age_range":{
    "gt":20,
    "lt":30
  }
}
相关推荐
得物技术1 天前
从埋点需求到规则资产:Hermes Agent 重构得物数仓工作流
大数据·llm·ai编程
久美子1 天前
AI驱动数仓建设的Harness工程实践——本体建模、知识分层与上下文工程
大数据
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
大志哥1232 天前
ES和Logstash日志链路系统上线后遭遇切片爆炸(解决)
大数据·elasticsearch
果丁智能2 天前
物联网智能锁赋能集中式住宿:身份核验与远程权限管控的全链路技术实践
大数据·人工智能·物联网·智能家居
ApacheSeaTunnel2 天前
实战演示 | 基于 Apache SeaTunnel 与 Apache DolphinScheduler 实现 MySQL 到 Doris 离线定时增量同步
大数据·mysql·开源·doris·数据集成·seatunnel·数据同步
weixin_397574092 天前
PDF复杂表格的1:1还原引擎:跨页表格自动拼接技术实战
大数据·人工智能·pdf
TableRow2 天前
参数化搜索的实现原理:从多维索引到查询优化
elasticsearch·全文检索
极光代码工作室2 天前
基于数据仓库的电商数据分析平台
大数据·hadoop·python·spark·数据可视化
秋名山码民2 天前
Graph RAG 深度解析:从向量检索到知识推理的技术演进
大数据·人工智能·rag