ElasticSearch7.3 学习之定制动态映射(dynamic mapping)
1、dynamic mapping
ElasticSearch中有一个非常重要的特性——动态映射,即索引文档前不需要创建索引、类型等信息,在索引的同时会自动完成索引、类型、映射的创建。
当ES在文档中碰到一个以前没见过的字段时,它会利用动态映射(dynamic mapping)来决定该字段的类型,并自动地对该字段添加映射。
有时这正是需要的行为,但有时不是,需要留意。你或许不知道在以后你的文档中会添加哪些字段,但是你想要它们能够被自动地索引。或许你只是想要忽略它们。或者,尤其当你将ES当做主要的数据存储使用时,大概你会希望这些未知的字段会抛出异常来提醒你注意这一问题。
幸运的是,你可以通过dynamic设置来控制这一行为,它能够接受以下的选项:
true:默认值。动态添加字段false:新检测到的字段将被忽略。这些字段将不会被索引,因此将无法搜索,但仍将出现在返回点击的源字段中。这些字段不会添加到映射中,必须显式添加新字段。strict:如果碰到陌生字段,抛出异常
dynamic设置可以适用在根对象上或者object类型的任意字段上。你应该默认地将dynamic设置为strict,但是为某个特定的内部对象启用它:
创建mapping
PUT /my_index
{
"mappings": {
"dynamic": "strict",
"properties": {
"title": {
"type": "text"
},
"address": {
"type": "object",
"dynamic": "true"
}
}
}
插入数据
PUT /my_index/_doc/1
{
"title": "my article",
"content": "this is my article",
"address": {
"province": "guangdong",
"city": "guangzhou"
}
}
报错,原因为content为新增字段。会抛出异常
{
"error": {
"root_cause": [
{
"type": "strict_dynamic_mapping_exception",
"reason": "mapping set to strict, dynamic introduction of [content] within [_doc] is not allowed"
}
],
"type": "strict_dynamic_mapping_exception",
"reason": "mapping set to strict, dynamic introduction of [content] within [_doc] is not allowed"
},
"status": 400
}
2、自定义 dynamic mapping策略
2.1 数据类型
如果你知道你需要动态的添加的新字段,那么你也许会启用动态映射。然而有时动态映射的规则又有些不够灵活。幸运的是,你可以调整某些设置来让动态映射的规则更加适合你的数据。
es会根据传入的值,推断类型,具体如下表所示。
|
JSON data type |
Elasticsearch data type |
ES中的数据类型 |
|
|
No field is added. |
不会添加字段 |
|
|
|
boolean |
|
floating point number |
|
double |
|
integer |
|
long |
|
object |
|
object |
|
array |
Depends on the first non- |
依赖于第一个非null得值 |
|
string |
Either a |
如果通过了date检测,则为date 如果通过了numeric检测,则为Number |
2.2 date_detection 日期探测
默认会按照一定格式识别date,比如yyyy-MM-dd。但是如果某个field先过来一个2017-01-01的值,就会被自动dynamic mapping成date,后面如果再来一个"hello world"之类的值,就会报错。可以手动关闭某个type的date_detection,如果有需要,自己手动指定某个field为date类型。
首先删除上面新建的索引
DELETE my_index
然后下面的语句代表的含义为:日期探测为false,表示可添加不是date数据类型的字段,也不会被推断成date类型。address字段里面为true,代表可动态往里面添加新的字段。
PUT /my_index
{
"mappings": {
"date_detection": false,
"properties": {
"title": {
"type": "text"
},
"address": {
"type": "object",
"dynamic": "true"
}
}
}
}
测试插入数据。下面的语句代表最外层级新增content、post_date两个字段,address层级新增province、city字段。
PUT /my_index/_doc/1
{
"title": "my article",
"content": "this is my article",
"address": {
"province": "guangdong",
"city": "guangzhou"
},
"post_date": "2019-09-10"
}
查看映射
GET /my_index/_mapping
返回,可以看到字段都成功新增,日期检测(date_detection)为false,所以post_date字段类型不是date类型。
{
"my_index" : {
"mappings" : {
"date_detection" : false,
"properties" : {
"address" : {
"dynamic" : "true",
"properties" : {
"city" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"province" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"content" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"post_date" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"title" : {
"type" : "text"
}
}
}
}
}
下面为自定义日期格式语法,读者可自行试验。
PUT my_index
{
"mappings": {
"dynamic_date_formats": ["MM/dd/yyyy"]
}
}
插入数据
PUT my_index/_doc/1
{
"create_date": "09/25/2019"
}
2.3 numeric_detection 数字探测
虽然json支持浮点和整数数据类型,但某些应用程序或语言有时可能需要将数字呈现为字符串。通常正确的解决方案是显式地映射这些字段,但是可以启用数字检测(默认情况下禁用)来自动完成这些操作。
首先删除上面新建的索引
DELETE my_index
然后开启数字检测
PUT my_index
{
"mappings": {
"numeric_detection": true
}
}
插入数据
PUT my_index/_doc/1
{
"my_float": "1.0",
"my_integer": "1"
}
查看映射
GET my_index/_mapping
返回
{
"my_index" : {
"mappings" : {
"numeric_detection" : true,
"properties" : {
"my_float" : {
"type" : "float"
},
"my_integer" : {
"type" : "long"
}
}
}
}
}
可以看到两个字段被映射为浮点类型了。
3、定制dynamic mapping template
通过dynamic_templates,你可以拥有对新字段的动态映射规则拥有完全的控制。你设置可以根据字段名称或者类型来使用一个不同的映射规则。
每个模板都有一个名字,可以用来描述这个模板做了什么。同时它有一个mapping用来指定具体的映射信息,和至少一个参数(比如match)用来规定对于什么字段需要使用该模板。
首先删除上面新建的索引
DELETE my_index
运行下面的语句,代表的含义为:匹配以_en结尾并且是string类型的字段,设置它的type为text,使用english分词。
PUT /my_index
{
"mappings": {
"dynamic_templates": [
{
"en": {
"match": "*_en",
"match_mapping_type": "string",
"mapping": {
"type": "text",
"analyzer": "english"
}
}
}
]
}
}
插入数据
PUT /my_index/_doc/1
{
"title": "this is my first article"
}
PUT /my_index/_doc/2
{
"title_en": "this is my first article"
}
查看映射
GET my_index/_mapping
返回,可以看到title_en字段采用english分词器,说明模板生效了。
{
"my_index" : {
"mappings" : {
"dynamic_templates" : [
{
"en" : {
"match" : "*_en",
"match_mapping_type" : "string",
"mapping" : {
"analyzer" : "english",
"type" : "text"
}
}
}
],
"properties" : {
"title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"title_en" : {
"type" : "text",
"analyzer" : "english"
}
}
}
}
}
搜索
GET my_index/_search?q=first
GET my_index/_search?q=is
title字段没有匹配到任何的dynamic模板,默认就是standard分词器,不会过滤停用词,is会进入倒排索引,用is来搜索是可以搜索到的
title_en字段匹配到了dynamic模板,就是english分词器,会过滤停用词,is这种停用词就会被过滤掉,用is来搜索就搜索不到了
4、模板写法
下面给出了一些大概的写法,读者可根据自身实际需求自定义模板
PUT my_index
{
"mappings": {
"dynamic_templates": [
{
"integers": {
"match_mapping_type": "long",
"mapping": {
"type": "integer"
}
}
},
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
]
}
}
模板参数:匹配满足的字段、不匹配满足的字段、匹配的数据类型、路径匹配、路径不匹配。
"match": "long_*",
"unmatch": "*_text",
"match_mapping_type": "string",
"path_match": "name.*",
"path_unmatch": "*.middle",
"match_pattern": "regex",
"match": "^profit_\d+$"
5、应用场景
5.1 结构化搜索
默认情况下,elasticsearch将字符串字段映射为带有子关键字(keyword)字段的文本字段。但是,如果只对结构化内容进行索引,而对全文搜索不感兴趣,则可以仅将“字段”映射为“关键字”。但是请注意,这意味着为了搜索这些字段,必须搜索索引所用的完全相同的值。
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
5.2 仅搜索
与前面的示例相反,如果您只关心字符串字段的全文搜索,并且不打算对字符串字段运行聚合、排序或精确搜索,您可以将其仅映射为文本字段(这是es5之前的默认行为)
{
"strings_as_text": {
"match_mapping_type": "string",
"mapping": {
"type": "text"
}
}
}
5.3 norms 不关心评分
当计算得分的时候,是否需要把字段长度用作参数计算。
尽管计算得分时把字段长度考虑在内可以提高得分的精确性,但这样会消耗大量的磁盘空间(每个文档的每个字段都会消耗一个字节,即使某些文档不包含这个字段)。因此,如果不需要计算字段的得分,你应该禁用该字段的norms。特别是这个字段仅用于聚合或者过滤。
{
"properties": {
"title": {
"type": "text",
"norms": false
}
}
}
ElasticSearch7.3 学习之定制动态映射(dynamic mapping)的更多相关文章
- ES 12 - 配置使用Elasticsearch的动态映射 (dynamic mapping)
目录 1 动态映射(dynamic mapping) 1.1 什么是动态映射 1.2 体验动态映射 1.3 搜索结果不一致的原因分析 2 开启dynamic mapping策略 2.1 约束策略 2. ...
- 聊聊elasticsearch7.8的模板和动态映射
最近想写一篇es的索引的一个设计,由于设计的东西特别多,当然,elasticsearch的模板和动态映射也是其中的一个设计点,所以干脆先来聊聊索引的模板和动态映射,模板,听这个名字就相当于一些公共可用 ...
- ElasticSearch7.3 学习之定制分词器(Analyzer)
1.默认的分词器 关于分词器,前面的博客已经有介绍了,链接:ElasticSearch7.3 学习之倒排索引揭秘及初识分词器(Analyzer).这里就只介绍默认的分词器standard analyz ...
- ElasticSearch7.3 学习之Mapping核心数据类型及dynamic mapping
1.mapping的核心数据类型以及dynamic mapping 1.1 核心的数据类型 string :text and keyword,byte,short,integer,long,float ...
- 2018/2/13 ElasticSearch学习笔记三 自动映射以及创建自动映射模版,ElasticSearch聚合查询
终于把这些命令全敲了一遍,话说ELK技术栈L和K我今天花了一下午全部搞定,学完后还都是花式玩那种...E却学了四天(当然主要是因为之前上班一直没时间学,还有安装服务时出现的各种error真是让我扎心了 ...
- 使用Logstash创建ES映射模版并进行数据默认的动态映射规则
本文配置为 ELK 即(Elasticsearch.Logstash.Kibana)5.5.1. Elasticsearch 能够自动检测字段的类型并进行映射,例如引号内的字段映射为 String,不 ...
- Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置
Asp.Net SignalR 使用记录 工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...
- Java的动态代理(dynamic proxy)
什么是动态代理(dynamic proxy) 动态代理(以下称代理),利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对 ...
- ASP.NET路由系统实现原理:HttpHandler的动态映射
我们知道一个请求最终通过一个具体的HttpHandler进行处理,而我们熟悉的用于表示一个Web页面的Page对象就是一个HttpHandler,被用于处理基于某个.aspx文件的请求.我们可以通过H ...
随机推荐
- ConcurrentHashMap怎么保证安全的
HashMap是一个线程不安全的容器,当容量大于总量*负载因子发生扩容时可能会出现环形链表从而导致死循环 扩容就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中,在多线程的环境下, ...
- Spring Cloud之微服务注册到Eureka Server集群后访问改造
上篇Spring Cloud之服务注册中心搭建Eureka Server服务注册中⼼ - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)已经已经成功将两个微服务注册到集群中,那么能正常能与注 ...
- Django创建第一个应用App(3)
创建一个投票的应用app.现在已经创建好了一个项目,就是有了一个框架,有了框架之后就可以往框架里面填写一些自己的需求,就是放一些功能在里面即可.一个项目可以包含多个应用app,一个应用app可以属于多 ...
- python-利用pymysql获取数据简单使用总结
python-利用pymysql获取数据库中的数据 1.前言 pymysql是一个第三方的模块,使用前需要安装 2.安装 pip install pymysql 3.基本使用 import pymys ...
- 微服务从代码到k8s部署应有尽有系列(八、各种队列)
我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...
- C# 中的Stream流
流就是一个类的对象,很多文件的输入输出操作都以类的成员函数的方式来提供: 流其实是一种信息的转换,是有序的,有输入和输出流(IO); 1.FileStream 文件流,读取和保存文件操作使用: //写 ...
- 使用教程:宝塔服务器管理助手Linux面版
网页提示:宝塔Linux面板初始化成功,点击登陆页面:直接使用初始化配置时填写的帐号及密码登陆面板功能:网站管理.FTP管理.数据库管理.系统安全.文件管理.计划任务.环境设置. 方法/步骤1: 使用 ...
- java集合框架中contains(),containsKey()和containsValue()的用法:
List集合的contains()方法用于判断集合中包不包含某个元素,返回值是boolean. Map集合的containsKey()和containsValue()方法和上面的相同. 示例: pub ...
- 基于COCO数据集验证的目标检测算法天梯排行榜
基于COCO数据集验证的目标检测算法天梯排行榜 AP50 Rank Model box AP AP50 Paper Code Result Year Tags 1 SwinV2-G (HTC++) 6 ...
- selenium+python自动化105 - selenium 如何在已打开的浏览器上继续运行自动化脚本?
前言 使用selenium 做web自动化的时候,经常会遇到这样一种需求,是否可以在已经打开的浏览器基础上继续运行自动化脚本? 这样前面的验证码登录可以手工点过去,后面页面使用脚本继续执行,这样可以解 ...