参考:

https://es.xiaoleilu.com/052_Mapping_Analysis/00_Intro.html

1. 概念

映射(mapping)机制用于进行字段类型确认,将每个字段匹配为一种确定的数据类型(string, number, booleans, date等)。

分析(analysis)机制用于进行全文文本(Full Text)的分词,以建立供搜索用的反向索引。

2. 数据类型差异

GET /gb/_mapping

返回:

{
"gb" : {
"mappings" : {
"properties" : {
"date" : {
"type" : "date"
},
"email" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"tweet" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"user_id" : {
"type" : "long"
},
"username" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}

查询:

GET /gb/_search?q=2019            # 返回空
GET /gb/_search?q=2019-12-12 # 返回3个结果
GET /gb/_search?q=date:2019-12-12 # 返回3个结果
GET /gb/_search?q=date:2019 # 返回空

可以,是因为date被es推测为date类型,而_all里是string类型,只会完整匹配2019-12-12。

3. 确切值VS全文索引

确切值 及 全文文本:

确切值是确定的,正如它的名字一样。比如一个date或用户ID,也可以包含更多的字符串比如username或email地址。

确切值"Foo"和"foo"就并不相同。确切值2014和2014-09-15也不相同。

全文文本,从另一个角度来说是文本化的数据(常常以人类的语言书写),比如一篇推文(Twitter的文章)或邮件正文。

全文文本常常被称为非结构化数据,其实是一种用词不当的称谓,实际上自然语言是高度结构化的。

问题是自然语言的语法规则是如此的复杂,计算机难以正确解析。例如这个句子:

May is fun but June bores me.

到底是说的月份还是人呢?

确切值是很容易查询的,因为结果是二进制的 -- 要么匹配,要么不匹配。下面的查询很容易以SQL表达:

WHERE name    = "John Smith"
AND user_id = 2
AND date > "2014-09-15"

4. 倒排索引

单词 -》 文档Id

5. 分析

  • 当你查询全文(full text)字段,查询将使用相同的分析器来分析查询字符串,以产生正确的词列表。
  • 当你查询一个确切值(exact value)字段,查询将不分析查询字符串,但是你可以自己指定。

5.1 测试分析器

尤其当你是Elasticsearch新手时,对于如何分词以及存储到索引中理解起来比较困难。为了更好的理解如何进行,你可以使用analyze API来查看文本是如何被分析的。在查询字符串参数中指定要使用的分析器,被分析的文本做为请求体:

GET /_analyze?analyzer=standard&text=Text to analyze

结果中每个节点在代表一个词:

{
"tokens": [
{
"token": "text",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "to",
"start_offset": 5,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "analyze",
"start_offset": 8,
"end_offset": 15,
"type": "<ALPHANUM>",
"position": 3
}
]
}

这个例子在es7.5版本报错。

为了手动指定特定字段的分析器,我们必须通过映射(mapping)人工设置这些字段。

6. 映射

在上面查询映射中,GET /gb/_mapping返回字段的映射关系。

index参数控制字符串以何种方式被索引。它包含以下三个值当中的一个:

  • analyzed 首先分析这个字符串,然后索引。换言之,以全文形式索引此字段。
  • not_analyzed 索引这个字段,使之可以被搜索,但是索引内容和指定值一样。不分析此字段。
  • no 不索引这个字段。这个字段不能为搜索到。

对于analyzed类型的字符串字段,使用analyzer参数来指定哪一种分析器将在搜索和索引的时候使用。默认的,Elasticsearch使用standard分析器,但是你可以通过指定一个内建的分析器来更改它,例如whitespace、simple或english。

{
"tweet": {
"type": "string",
"analyzer": "english"
}
}

6.1 更新映射

你可以在第一次创建索引的时候指定映射的类型。此外,你也可以晚些时候为新类型添加映射(或者为已有的类型更新映射)。

重要:

你可以向已有映射中增加字段,但你不能修改它。如果一个字段在映射中已经存在,这可能意味着那个字段的数据已经被索引。如果你改变了字段映射,那已经被索引的数据将错误并且不能被正确的搜索到。

7. 复合类型

7.1 多值字段

我们想让tag字段包含多个字段,这非常有可能发生。我们可以索引一个标签数组来代替单一字符串:

{ "tag": [ "search", "nosql" ]}

对于数组不需要特殊的映射。任何一个字段可以包含零个、一个或多个值,同样对于全文字段将被分析并产生多个词。

言外之意,这意味着数组中所有值必须为同一类型。你不能把日期和字符窜混合。如果你创建一个新字段,这个字段索引了一个数组,Elasticsearch将使用第一个值的类型来确定这个新字段的类型。

当你从Elasticsearch中取回一个文档,任何一个数组的顺序和你索引它们的顺序一致。你取回的_source字段的顺序同样与索引它们的顺序相同。

然而,数组是做为多值字段被索引的,它们没有顺序。在搜索阶段你不能指定“第一个值”或者“最后一个值”。倒不如把数组当作一个值集合(bag of values)

7.2 空字段

当然数组可以是空的。这等价于有零个值。事实上,Lucene没法存放null值,所以一个null值的字段被认为是空字段。

这四个字段将被识别为空字段而不被索引:

"empty_string": "",

"null_value": null,

"empty_array": [],

"array_with_null_value": [ null ]

7.3 多层对象

我们需要讨论的最后一个自然JSON数据类型是对象(object)——在其它语言中叫做hash、hashmap、dictionary 或者 associative array.

内部对象(inner objects)经常用于在另一个对象中嵌入一个实体或对象。例如,做为在tweet文档中user_name和user_id的替代,我们可以这样写:

{
"tweet": "Elasticsearch is very flexible",
"user": {
"id": "@johnsmith",
"gender": "male",
"age": 26,
"name": {
"full": "John Smith",
"first": "John",
"last": "Smith"
}
}
}

7.4 内部对象的映射

Elasticsearch 会动态的检测新对象的字段,并且映射它们为 object 类型,将每个字段加到 properties 字段下

{
"gb": {
"tweet": { <1>
"properties": {
"tweet": { "type": "string" },
"user": { <2>
"type": "object",
"properties": {
"id": { "type": "string" },
"gender": { "type": "string" },
"age": { "type": "long" },
"name": { <3>
"type": "object",
"properties": {
"full": { "type": "string" },
"first": { "type": "string" },
"last": { "type": "string" }
}
}
}
}
}
}
}
}

<1> 根对象.

<2><3> 内部对象.

对user和name字段的映射与tweet类型自己很相似。事实上,type映射只是object映射的一种特殊类型,我们将 object 称为根对象。它与其他对象一模一样,除非它有一些特殊的顶层字段,比如 _source, _all 等等。

7.5 内部对象是怎样被索引的

Lucene 并不了解内部对象。 一个 Lucene 文件包含一个键-值对应的扁平表单。 为了让 Elasticsearch 可以有效的索引内部对象,将文件转换为以下格式:

{
"tweet": [elasticsearch, flexible, very],
"user.id": [@johnsmith],
"user.gender": [male],
"user.age": [26],
"user.name.full": [john, smith],
"user.name.first": [john],
"user.name.last": [smith]
}

7.6 内部对象数组

最后,一个包含内部对象的数组如何索引。 我们有个数组如下所示:

{
"followers": [
{ "age": 35, "name": "Mary White"},
{ "age": 26, "name": "Alex Jones"},
{ "age": 19, "name": "Lisa Smith"}
]
}

此文件会如我们以上所说的被扁平化,但其结果会像如此:

{
"followers.age": [19, 26, 35],
"followers.name": [alex, jones, lisa, smith, mary, white]
}

{age: 35}与{name: Mary White}之间的关联会消失,因每个多值的栏位会变成一个值集合,而非有序的阵列。 这让我们可以知道:

  • 是否有26岁的追随者?

但我们无法取得准确的资料如:

  • 是否有26岁的追随者且名字叫Alex Jones?

关联内部对象可解决此类问题。

ES-映射和分析的更多相关文章

  1. elasticsearch(6) 映射和分析

    类似关系型数据库中每个字段都有对应的数据类型,例如nvarchar.int.date等等,elasticsearch也会将文档中的字段映射成对应的数据类型,这一映射可以使ES自动生成的,也是可以由我们 ...

  2. elasticsearch映射及分析-----3

    首先我们看下不同的索引方式相同的字段指定字段类型与不指定字段类型es会怎么处理 1.不指定类型,直接创建索引及类型文档 我们看下他默认的索引映射 2.创建索引和类型时指定字段类型 这里创建了一个索引为 ...

  3. ElasticSearch 5学习(9)——映射和分析(string类型废弃)

    在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...

  4. ElasticSearch权威指南学习(映射和分析)

    概念 映射(mapping)机制用于进行字段类型确认,将每个字段匹配为一种确定的数据类型(string, number, booleans, date等).+ 分析(analysis)机制用于进行全文 ...

  5. 使用Logstash创建ES映射模版并进行数据默认的动态映射规则

    本文配置为 ELK 即(Elasticsearch.Logstash.Kibana)5.5.1. Elasticsearch 能够自动检测字段的类型并进行映射,例如引号内的字段映射为 String,不 ...

  6. linux kernel内存映射实例分析

    作者:JHJ(jianghuijun211@gmail.com)日期:2012/08/24 欢迎转载,请注明出处 引子 现在android智能手机市场异常火热,硬件升级非常迅猛,arm cortex ...

  7. KVm中EPT逆向映射机制分析

    2017-05-30 前几天简要分析了linux remap机制,虽然还有些许瑕疵,但总算大致分析的比较清楚.今天分析下EPT下的逆向映射机制.EPT具体的工作流程可参考前面博文,本文对于EPT以及其 ...

  8. ES中的分析和分析器

    在ES存储的文档,进行存储时,会对文档的内容进行分析和分词 分析的过程: 首先,将一块文本分成适合于倒排索引的独立的 词条 , 之后,将这些词条统一化为标准格式以提高它们的“可搜索性”,或者 reca ...

  9. elasticsearch7.6.2实战(2)-es可视化及分析平台-kibana

    1. 场景描述 elasticsearch部署完成后,es官方提供了可视化.分析及管理平台-kibana,部署下,有需要朋友参考下,不谢! 2. 解决方案 2.1 下载 (1)地址:https://w ...

  10. 【ElasticSearch】 使用AWS云ES服务来分析程序日志

    最近公司系统升级,有些API的调用接口达到了每天10几万的请求量.目前公司里的日志,都是写文本文件中的.为了能够更好的分析这些日志数据,公司采用了AWS 的 ElasticSearch服务来分析日志. ...

随机推荐

  1. 超好用的自带火焰图的 Java 性能分析工具 Async-profiler 了解一下

    如果你经常遇到 Java 线上性能问题束手无策,看着线上服务 CPU 飙升一筹莫展,发现内存不断泄露满脸茫然.别慌,这里有一款低开销.自带火焰图.让你大呼好用的 Java 性能分析工具 - async ...

  2. pod install速度慢解决方案

    相信大家已经感受到pod install速度越来越慢了,网上提供了几种解决方案,但是都没有完全解决速度慢的问题. 使用国内镜像的Specs 在pod install时使用命令pod install - ...

  3. webpack4.0(二)--热更新

    webpack4.0---热更新 使用webpack可帮助我们的开发以及打包,在开发过程中,有时候我们只修改了部分代码并想不必刷新整个页面即可看到更改后的效果,这时候 webpack-dev-serv ...

  4. Python协程与Go协程的区别二

    写在前面 世界是复杂的,每一种思想都是为了解决某些现实问题而简化成的模型,想解决就得先面对,面对就需要选择角度,角度决定了模型的质量, 喜欢此UP主汤质看本质的哲学科普,其中简洁又不失细节的介绍了人类 ...

  5. Android多线程之(一)——View.post()篇

    前言 提起View.post(),相信不少童鞋一点都不陌生,它用得最多的有两个功能,使用简便而且实用: 1)在子线程中更新UI.从子线程中切换到主线程更新UI,不需要额外new一个Handler实例来 ...

  6. Xcode10:The operation couldn’t be completed. (DVTCoreSimulatorAdditionsErrorDomain error 0.)

    目录 Xcode10 build success,但是模拟器Simulator不能正常启动,报错如下: 解决方案: Xcode10 build success,但是模拟器Simulator不能正常启动 ...

  7. mininet(二)简单的路由实验

    mininet(一)实验环境搭建 mininet(二)简单的路由实验 mininet(三)简单的NAT实验 在网上找了 好几个代码都是不能直接复现成功,这里把自己实现成功的代码给大家演示一下. 实验的 ...

  8. python之pymysql模块简单应用

    众所周知,想要在python程序中执行SQL语句需要使用第三方模块:pymysql. 下面,我将为大家简述一下pymysql第三方库的安装到使用的大体流程. pymysql的安装 1.windows系 ...

  9. Spring Boot 外部化配置(一)- Environment、ConfigFileApplicationListener

    目录 前言 1.起源 2.外部化配置的资源类型 3.外部化配置的核心 3.1 Environment 3.1.1.ConfigFileApplicationListener 3.1.2.关联 Spri ...

  10. 通信协议TLV的介绍及在python下的代码实现及仿真

    TLV协议是一种通讯协议,一般将数据封装成TLV的形式,即Tag,Length,Value.协议就是指通信双方对数据传输控制的一种规定,规定了数据格式,同步方式,传送速度,传送步骤的问题作出统一的规定 ...