Elasticsearch学习笔记(七)—Elasticsearch分析器与映射

一、确切值(Exact values) vs 全文文本(Full text)

Elasticsearch中的数据可以大致分为两种类型

  • 确切值,确切值是确定的,正如它的名字一样。比如一个date或用户ID,需要精确匹配,对于2019-11-8,只输入2019-11是不能被检索出来,必须精确匹配
  • 全文文本,Elasticsearch会对文本分析(analyzes),然后使用结果建立一个倒排索引,比如,可以支持模糊匹配,忽略大小写,近义词匹配

二、Elasticsearch分析器

分析器需要完成以下分析过程:

  • 表征化一个文本块为适用于倒排索引单独的词(term)
  • 然后标准化这些词为标准形式,提高他们的“可搜索性”

ES分析器组成:

  • 字符过滤器
    首先字符串经过过滤器(character filter),他们的工作是在表征化前处理字符串。字符过滤器能够去除HTML标记,或者转化为“&”为“and”
  • 分词器( Tokenizers ) 可以根据空格或逗号将单词分开
    分词器(tokenizer)被表征化为独立的词。一个简单的分词器(tokenizer)可以根据空格或逗号将单词分开(注:这个在中文中不适用)
  • 标记过滤器 ( token filters )
    每个词都通过所有表征过滤(token filters),可以修改词(例如将“Quick”转为小写),去掉词(例如停用词像“a”、“and”、“the”等等),或者增加词(例如同义词像“a”、“and”、“the”等等)或者增加词(例如同义词像“jump”和“leap”)

内置分析器

  • 标准分析器,Elasticsearch默认使用的分析器,它是分析各种语言文本最常用的选择,根据 Unicode 联盟 定义的 单词边界 划分文本。删除绝大部分标点。最后,将词条小写
  • 简单分析器,在任何不是字母的地方分隔文本,将词条小写
  • 空格分析器,在空格的地方划分文本
  • 语言分析器,可以考虑指定语言的特点

什么时候使用分析器?
当我们索引一个文档,它的全文域被分析成词条以用来创建倒排索引。 但是,当我们在全文域搜索 的时候,我们需要将查询字符串通过 相同的分析过程 ,以保证我们搜索的词条格式与索引中的词条格式一致

  • 当你查询一个全文域时, 会对查询字符串应用相同的分析器,以产生正确的搜索词条列表。
  • 当你查询一个精确值域时,不会分析查询字符串,而是搜索你指定的精确值

三、映射介绍

数据库中的表,我们一般在DDL语句中为每个字段指定存储类型,例如:varchar,int,datetime等等,目的很明确,就是更精确的存储数据,防止数据类型格式混乱

类比数据库,ES的索引字段也需要为其指定类型,它就像数据库中的 schema,这种在ES称为映射(mapping)

映射是定义一个文档及其包含的字段如何存储和索引的过程,可以从以下几个方面理解:

  • 将哪些字符串字段视为全文字段
  • 哪些字段包含数字,日期或地理位置
  • 日期值的格式
  • 自定义规则以控制动态添加字段的映射

动态映射: 文档写入es时,es可根据写入内容的类型自动识别,生成mapping
静态映射: 手动为索引指定字段类型

四、字段类型

JSON格式的数据自动推测字段类型
null没有字段被添加
true or falseboolean
浮点类型数字float类型
数字long类型
JSON对象object类型
数组由数组中第一个非空值决定
string有可能是date类型(开启日期检测)、double或long类型、text类型、keyword类型

text 和 keyword 的区别:

  • text 用于索引全文值的字段,例如电子邮件正文或产品说明。这些字段是analyzed,它们通过分词器传递 ,以在被索引之前将字符串转换为单个术语的列表。分析过程允许Elasticsearch搜索单个单词中 每个完整的文本字段。文本字段不用于排序,很少用于聚合
  • keyword 用于索引结构化内容的字段,例如电子邮件地址,主机名,状态代码,邮政编码或标签。它们通常用于过滤,排序,和聚合。keyword字段只能按其确切值进行搜索。如果您需要索引电子邮件正文或产品说明等全文内容,则可能应该使用text字段

有时候单纯的一个字段类型满足不了我们复杂的需求,为了不同的目的,以不同的方式索引同一个字段通常很有用,例如,对于字符串字段,我们既可以将它映射为text类型用于全文搜索,亦可以将它映射为keyword类型用于排序或聚合,或者,还可以使用标准分词器、英语分词器和其他语言分词器索引文本字段

前面说过,当 Elasticsearch 遇到文档中以前 未遇到的字段,它用 dynamic mapping 来确定字段的数据类型并自动把新的字段添加到类型映射。

如果不希望这样,可以使用dynamic参数设置

  • true,动态添加新的字段
  • false,忽略新的字段
  • strict,如果遇到新字段抛出异常

配置参数 dynamic 可以用在根 object 或任何 object 类型的字段上。你可以将 dynamic 的默认值设置为 strict , 而只在指定的内部对象中开启它, 例如:

PUT /my_index
{
    "mappings": {
        "my_type": {
            "dynamic":      "strict", 
            "properties": {
                "title":  { "type": "string"},
                "stash":  {
                    "type":     "object",
                    "dynamic":  true 
                }
            }
        }
    }
}
  • 如果遇到新字段,对象 my_type 就会抛出异常
  • 内部对象 stash 遇到新字段就会动态创建新字段

参考

Elasticsearch权威指南

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值