Elasticsearch实践:Setting、Mapping

版本:Elasticsearch 6.2.4。

Mapping类似于数据库中的表结构定义,主要作用如下:

  • 定义Index下字段名(Field Name)
  • 定义字段的类型,比如数值型,字符串型、布尔型等
  • 定义倒排索引的相关配置,比如是否索引、记录postion等

Mapping完整的内容可以分为四部分内容:

  • 字段类型(Field datatypes)
  • 元字段(Meta-Fields)
  • Mapping参数配置(Mapping parameters)
  • 动态Mapping(Dynamic Mapping)

自动Mapping

如果没有手动设置Mapping,Elasticsearch默认会自动解析出类型,且每个字段以第一次出现的为准。

下面我们先看一下Elasticsearch默认创建的Mapping是什么样的。

首先我们创建一个索引:

PUT /user/

查询索引信息:

GET /user

结果:

{
  "user": {
    "aliases": {},"mappings": {},"settings": {
      "index": {
        "creation_date": "1540044686190","number_of_shards": "5","number_of_replicas": "1","uuid": "_K5b8w7jRiuthf7QeQZhdw","version": {
          "created": "5060299"
        },"provided_name": "user"
      }
    }
  }
}

增加一条数据:

PUT /user/doc/1
{
  "name":"Allen Yer","job":"php","age":22
}

PUT /user/doc/2
{
  "name":"Allen Yer","job":0,"age":22
}

查询数据是否新增成功:

GET /user/doc/_count

结果:

{
  "count": 2,"_shards": {
    "total": 5,"successful": 5,"skipped": 0,"failed": 0
  }
}

count为2,说明新增成功。然后我们查询下 mapping :

{
  "user": {
    "mappings": {
      "doc": {
        "properties": {
          "age": {
            "type": "long"
          },"job": {
            "type": "text","fields": {
              "keyword": {
                "type": "keyword","ignore_above": 256
              }
            }
          },"name": {
            "type": "text","ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

发现自动为每个字段设置了类型:

  • name: text类型,另外额外增加了name.keyword字段,keyword类型;
  • job:text类型,另外额外增加了job.keyword字段,keyword类型;虽然第二次数据新增是数字类型,但还是以第一次为主;
  • age:long类型。

大家可以把索引删掉,将新增数据调整为先新增第2条,再新增第一条,发现报错了:

DELETE /user

PUT /user/doc/2
{
  "name":"Allen Yer","age":22
}

PUT /user/doc/1
{
  "name":"Allen Yer","age":22
}

报错:

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception","reason": "failed to parse [job]"
      }
    ],"type": "mapper_parsing_exception","reason": "failed to parse [job]","caused_by": {
      "type": "number_format_exception","reason": "For input string: \"php\""
    }
  },"status": 400
}

也能说明以第一次为主以字段第一次的值类型为准。这也说明了默认创建mapping可能不是我们想要的,这就需要手动创建mapping,好处有:

  • 提前指定字段(通过设置甚至可以达到禁止自动增加字段的效果)
  • 合理设置字段类型,防止分词过多或者解析不合理。分词过大会导致磁盘空间占用大。

手动创建mapping

这次我们删掉mapping,并手动创建一个:

DELETE /user

PUT /user/
{
    "mappings": {
      "doc": {
        "properties": {
          "name": {
            "type": "text","age": {
            "type": "long","index": false
          },"job": {
            "type": "keyword"
          },"intro":{
            "type":"text"
          },"create_time": {
            "type": "date","format": "epoch_second"
        }
        }
     }
  }
}

字段类型说明:

  • name:text类型,会进行分词,支持模糊检索。
  • name.keyword : 这相当于是嵌套了一个字段,keyword类型,只能精确匹配,不支持分词。超过256字符长度不索引,也就没法搜索到。
  • age:long类型,支持精确匹配。
  • job:keyword类型,只能精确匹配,不支持分词。
  • intro:text类型,会进行分词,支持模糊检索。
  • create_time:date类型,支持10位时间戳。
注意:mapping生成后是不允许修改(包括删除)的。所以需要提前合理的的定义mapping。

字段类型

Elasticsearch支持文档中字段的许多不同数据类型:

普通数据类型

字符串类型

text 和 keyword2种 。其中 text 支持分词,用于全文搜索;keyword 不支持分词,用于聚合和排序。在旧的ES里这两个类型由string表示。

如果安装了IK分词插件,我们可以为text类型指定IK分词器。一般来说,对于字符串类型,如果:

1) 模糊搜索+精确匹配,一般是name或者title字段:

"name": {
        "type": "text","analyzer": "ik_smart","fields": {
          "keyword": {
            "type": "keyword","ignore_above": 256
          }
        }
      }

2) 模糊搜索,一般是内容详情字段:

"content": {
        "type": "text","analyzer": "ik_smart"
      }

3) 精确匹配:

"name": {
        "type": "keyword"
      }

4) 不需要索引:

"url": {
        "type": "keyword","index": false
      }
数字类型

支持 long,integer,short,byte,double,float,half_float,scaled_float。具体说明如下:

  • long

带符号的64位整数,其最小值为-2^63,最大值为(2^63)-1

  • integer

带符号的32位整数,其最小值为-2^31,最大值为(23^1)-1

  • short

带符号的16位整数,其最小值为-32,768,最大值为32,767。

  • byte

带符号的8位整数,其最小值为-128,最大值为127。

  • double

双精度64位IEEE 754浮点数。

  • float

单精度32位IEEE 754浮点数。

  • half_float

半精度16位IEEE 754浮点数。

  • scaled_float

缩放类型的的浮点数。需同时配置缩放因子(scaling_factor)一起使用。

对于整数类型(byte,short,integer和long)而言,我们应该选择这是足以使用的最小的类型。这将有助于索引和搜索更有效。

对于浮点类型(float、half_float和scaled_float),-0.0+0.0是不同的值,使用term查询查找-0.0不会匹配+0.0,同样range查询中上边界是-0.0不会匹配+0.0,下边界是+0.0不会匹配-0.0

其中scaled_float,比如价格只需要精确到分,price57.34的字段缩放因子为100,存起来就是5734。优先考虑使用带缩放因子的scaled_float浮点类型。

示例:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "status": {
          "type": "byte"
        },"year": {
          "type": "short"
        },"id": {
          "type": "long"
        },"price": {
          "type": "scaled_float","scaling_factor": 100
        }
      }
    }
  }
}
日期类型

类型为 date 。

JSON本身是没有日期类型的,因此Elasticsearch中的日期可以是:

  • 包含格式化日期的字符串。
  • 一个13位long类型表示的毫秒时间戳( milliseconds-since-the-epoch)。
  • 一个integer类型表示的10位普通时间戳(seconds-since-the-epoch)。

在Elasticsearch内部,日期类型会被转换为UTC(如果指定了时区)并存储为long类型表示的毫秒时间戳。

日期类型可以使用使用format自定义,默认缺省值:"strict_date_optional_time||epoch_millis"

"postdate": {
      "type": "date","format": "strict_date_optional_time||epoch_millis"
    }

format 有很多内置类型,这里列举部分说明:

  • strict_date_optional_time,date_optional_time

通用的ISO日期格式,其中日期部分是必需的,时间部分是可选的。例如 "2015-01-01"或"2015/01/01 12:10:30"。

  • epoch_millis

13位毫秒时间戳

  • epoch_second

10位普通时间戳

其中strict_开头的表示严格的日期格式,这意味着,年、月、日部分必须具有前置0。

更多日期格式详见: https://www.elastic.co/guide/...

当然也可以自定义日期格式,例如:

"postdate":{
      "type":"date","format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
    }

注意:如果新文档的字段的值与format里设置的类型不兼容,ES会返回失败。示例:

PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "date": {
          "type": "date","format":"epoch_millis"
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
  "date":1543151405000
}
PUT my_index/_doc/2
{
  "date":1543151405
}
PUT my_index/_doc/3
{
  "date":"2018-11-25 21:10:43"
}
GET my_index/_doc/_search

第3条数据插入失败,因为只接受长整数的时间戳,字符串类型的日期是不匹配的。第2条的值只有10位数,虽然值是不正确的,但是在epoch_millis的取值范围内,所以也是成功的。

布尔类型

类型为 boolean 。

二进制类型

类型为 binary 。

范围类型

integer_range,float_range,long_range,double_range,date_range

复杂类型

  • 数组数据类型

在ElasticSearch中,没有专门的数组(Array)数据类型,但是,在默认情况下,任意一个字段都可以包含0或多个值,这意味着每个字段默认都是数组类型,只不过,数组类型的各个元素值的数据类型必须相同。在ElasticSearch中,数组是开箱即用的(out of box),不需要进行任何配置,就可以直接使用。,例如:

字符型数组: [ "one","two" ]
整型数组:[ 1,2 ]
数组型数组:[ 1,[ 2,3 ]] 等价于[ 1,2,3 ]

  • 对象数据类型

object 对于单个JSON对象。JSON天生具有层级关系,文档可以包含嵌套的对象。

  • 嵌套数据类型

nested 对于JSON对象的数组

Geo数据类型

  • 地理点数据类型

geo_point 对于纬度/经度点

  • Geo-Shape数据类型

geo_shape 对于像多边形这样的复杂形状

专用数据类型

  • IP数据类型

ip 用于IPv4和IPv6地址

  • 完成数据类型

completion 提供自动完成的建议

  • 令牌计数数据类型

token_count 计算字符串中的标记数

  • mapper-murmur3

murmur3 在索引时计算值的哈希值并将它们存储在索引中

  • 过滤器类型

接受来自query-dsl的查询

  • join 数据类型

为同一索引中的文档定义父/子关系

多字段

为不同目的以不同方式索引相同字段通常很有用。例如,string可以将字段映射为text用于全文搜索的keyword字段,以及用于排序或聚合的字段。或者,您可以使用standard分析仪, english分析仪和 french分析仪索引文本字段。

元字段

_all

该字段用于在没有指定具体字段的情况下进行模糊搜索,可以搜索全部字段的内容。

原理是将所有字段的内容视为字符串,拼在一起放在一个_all字段上,但这个字段默认是不被存储的,可以被搜索。在query_string与 simple_query_string查询(Kibana搜索框用的这种查询方式)默认也是查询_all字段。

6.x 版本被默认关闭。

相关设置:

PUT my_index
{
  "mappings": {
    "my_type": {
      "_all": {
        "enabled": true,"store": false
      },"properties": {}
    }
  },"settings": {
    "index.query.default_field": "_all" 
  }
}

上述配置在5.x版本是默认配置:

  • 默认开启 _all 字段
  • 默认不存储 _all 字段
  • 默认搜索 _all 字段

如果从CPU性能及磁盘空间考虑,可以考虑可以完全禁用或基于每个字段自定义_all字段。

假设_all字段被禁用,则URI搜索请求、 query_stringsimple_query_string查询将无法将其用于查询。我们可以将它们配置为其他字段:通过定义 index.query.default_field 属性。

_source

这个字段用于存储原始的JSON文档内容,本身不会被索引,但是搜索的时候被返回。如果没有该字段,虽然还能正常搜索,但是返回的内容不知道对应的是什么。

示例:

GET /user/doc/_search?q=name

结果:

{
  "took": 4,"timed_out": false,"failed": 0
  },"hits": {
    "total": 1,"max_score": 0.2876821,"hits": [
      {
        "_index": "user","_type": "doc","_id": "1","_score": 0.2876821,"_source": {
          "name": "this is test name","age": 22,"job": "java","intro": "the intro can not be searched by singal","intro2": "去朝阳公园","create_time": 1540047542
        }
      }
    ]
  }
}

搜索结果就包含_source字段,存储的是原始文档内容。如果被禁用,只知道有匹配内容,但是无法知道返回的是什么。所以需要谨慎关闭该字段。

如果想禁用该字段,可以在创建Mapping的时候,设置_:

{
  "mappings": {
    "_doc": {
      "_source": {
        "enabled": false
      }
    }
  }
}

_type

ElasticSearch里面有 index 和 type 的概念:index称为索引,type为文档类型,一个index下面有多个type,每个type的字段可以不一样。这类似于关系型数据库的 database 和 table 的概念。

但是,ES中不同type下名称相同的filed最终在Lucene中的处理方式是一样的。所以后来ElasticSearch团队想去掉type,于是在6.x版本为了向下兼容,一个index只允许有一个type。

该字段再在6.0.0中弃用。在Elasticsearch 6.x 版本中创建的索引只能包含单个type。在5.x中创建的含有多个type的索引将继续像以前一样在Elasticsearch 6.x中运行。type 将在Elasticsearch 7.0.0中完全删除。

原文地址:https://blog.csdn.net/u011807844/article/details/134739732

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读774次,点赞24次,收藏16次。typescript项目中我们使用typings-for-css-modules-loader来替代css-loader实现css modules。1、typings-for-css-modules-loader加载器介绍 Webpack加载器,用作css-loader的替代产品,可动态生成CSS模块的TypeScript类型这句话是什么意思呢?就是编译时处理css文件...
文章浏览阅读784次。react router redux antd eslint prettier less axios_react+antd+redux+less
文章浏览阅读3.9k次,点赞5次,收藏11次。需要删除.security-7索引文件。把在第1步中的被注释的配置打开。之后就是按照提示输入密码。执行bin目录下的文件。_failed to authenticate user 'elastic' against
文章浏览阅读1.2k次,点赞23次,收藏24次。Centos 8 安装es_centos8 yum elasticsearch
文章浏览阅读3.2k次。设置完之后,数据会⾃动同步到其他节点。修改密码时,将第⼀步配置删除,然后重启。单独使⽤⼀个节点⽣成证书;执⾏设置⽤户名和密码的命令。执⾏完上⾯命令以后就可以在。⽂件,在⾥⾯添加如下内容。这个⽂件复制到其他节点下。其中⼀个节点设置密码即可。依次对每个账户设置密码。全部节点都要重启⼀遍。需要在配置⽂件中开启。个⽤户分别设置密码,⽬录下,证书⽂件名为。功能,并指定证书位置。_es设置账号和密码
文章浏览阅读1.9k次,点赞2次,收藏7次。针对多数据源写入的场景,可以借助MQ实现异步的多源写入,这种情况下各个源的写入逻辑互不干扰,不会由于单个数据源写入异常或缓慢影响其他数据源的写入,虽然整体写入的吞吐量增大了,但是由于MQ消费是异步消费,所以不适合实时业务场景。不易出现数据丢失问题,主要基于MQ消息的消费保障机制,比如ES宕机或者写入失败,还能重新消费MQ消息。针对这种情况,有数据强一致性要求的,就必须双写放到事务中来处理,而一旦用上事物,则性能下降更加明显。可能出现延时问题:MQ是异步消费模型,用户写入的数据不一定可以马上看到,造成延时。_mysql同步es
文章浏览阅读3.6w次,点赞48次,收藏44次。【程序员洲洲送书福利-第十九期】《C++ Core Guidelines解析》
文章浏览阅读1.3k次。当我们在开发Vue应用时,经常需要对表单进行校验,以确保用户输入的数据符合预期。Vue提供了一个强大的校验规则机制,通过定义rules规则,可以方便地对表单进行验证,并给出相应的错误提示。_vue ruler校验
文章浏览阅读2k次,点赞16次,收藏12次。Linux内核源码下载地址及方式_linux源码下载
文章浏览阅读1k次。这样在每天自动生成的索引skywalking_log_xxx就会使用上述模版来生成,timestamp会被设置成date类型。然后此时在–>索引管理–>kibana–>索引模式添加skywalking_log*索引时就会有时间字段了。在通过skywalking将日志收集到es后,由于skywalking收集的日志(skywalking_log索引)没有date类型的字段导致在es上再索引模式中没有时间范围的查询。skywalking收集的日志有时间戳字段timestamp,只是默认为long类型。_skywalking timestamp
文章浏览阅读937次,点赞18次,收藏21次。1.初始化git仓库,使用git int命令。2.添加文件到git仓库,两步走:2.1 使用命令,注意,可反复多次使用,添加多个文件;2.2 使用命令,完成。此笔记是我个人学习记录笔记,通过廖雪峰的笔记进行学习,用自己能理解的笔记记录下来,如果侵权,联系删。不存在任何盈利性质,单纯发布后,用于自己学习回顾。
文章浏览阅读786次,点赞8次,收藏7次。上述示例中的 origin 是远程仓库的名称,https://github.com/example/repository.git 是远程仓库的 URL,(fetch) 表示该远程仓库用于获取更新,(push) 表示该远程仓库用于推送更新。你可以选择在本地仓库创建与远程仓库分支对应的本地分支,也可以直接将本地仓库的分支推送到远程仓库的对应分支。将 替换为远程仓库的名称(例如 origin), 替换为要推送的本地分支的名称, 替换为要推送到的远程分支的名称。_git remote 智能切换仓库
文章浏览阅读1.5k次。配置eslint校验代码工具_eslint 实时校验
文章浏览阅读1.2k次,点赞28次,收藏26次。Git入门基础介绍,什么是Git,如何使用Git,以及Git的工作的基本原理
文章浏览阅读2.7k次。基于官方给出的几种不同环境不同的安装方式,本文将会选择在使用.zip文件在Windows上安装Elasticsearch在Linux或macOS上从存档文件安装ElasticsearchInstall Elasticsearch with Docker (此种方式待定)使用Docker安装Elasticsearch。_elasticsearch安装部署windows
文章浏览阅读3.3k次,点赞5次,收藏11次。【Linux驱动】内核模块编译 —— make modules 的使用(单模块编译、多模块编译)_make modules
文章浏览阅读1k次。docker启动es报错_max virtual memory areas vm.max_map_count [65530] is too low, increase to at
文章浏览阅读4.2k次,点赞2次,收藏6次。使用docker单机安装elasticsearch后再安装kibana时找不到es。_unable to retrieve version information from elasticsearch nodes. security_ex
文章浏览阅读1.1k次。日志处理对于任何现代IT系统都是关键部分,本教程专为新手设计,通过详细解释Logstash的三大核心组件,为您展示如何从零开始搭建强大的日志处理系统。您还将学习如何同步MySQL数据到Elasticsearch,并通过一个"Hello World"示例快速入门。无论您是完全的新手还是有一些基础,本教程都将引导您顺利掌握Logstash的基本操作和高级应用。_logstash mysql
文章浏览阅读1.1w次,点赞5次,收藏25次。执行这条指令之后,你的本地项目就与远程Git仓库建立了连接,你就可以开始对你的代码进行版本追踪和协作开发了。使用“git remote add origin”指令,可以轻松地将本地项目连接到远程Git仓库。git remote set-url origin 执行这条指令之后,Git就会将已经添加的名为“origin”的仓库删除。git remote add origin 其中,是你的远程Git仓库的网址。_git remote add origin