Elasticsearch映射和分析

映射

Elasticsearch中的mapping(映射)对应数据库中的表结构

GET /gb/_mapping/tweet

返回:

QQ图片20170412153657.png

Elasticsearch核心简单字段类型:

类型   表示的数据类型
 String  string
 Whole number  byte, short, integer, long
 Floating point  float, double
 Boolean  boolean
 Date  date

当你索引一个包含新字段的文档——一个之前没有的字段——Elasticsearch将使用动态映射猜测字段类型,这类型来自于JSON的基本数据类型,使用以下规则:

JSON type   Field type
 Boolean: true or false  boolean
 Whole number: 123  long
 Floating point: 123.45  double
 String, valid date: "2014-09-15"  date
 String: "foo bar"  string

注意

这意味着,如果你索引一个带引号的数字——"123",它将被映射为"string"类型,而不是"long"类型。然而,如果字段已经被映射为"long"类型,Elasticsearch将尝试转换字符串为long,并在转换失败时会抛出异常。

使用技巧

我们可以先同步一条数据让ES自动生成映射,然后复制出来修改部分字段后手动创建映射

定义字段映射规则

前面说到,在同步一个新的字段时,ES会自动生成映射,但有时候默认的映射并不能满足我们的需求,幸运的是我们可以通过设置来自定义这些规则。

比如你不希望把"2014-09-15"的字段映射成date类型,可以使用:

扫描二维码关注公众号,回复: 2788446 查看本文章

"mappings": {
    "my_type": {
        "date_detection": false
    }

}

你也可以修改日期格式的映射规则,如:

"mappings": {
    "_default_": {
      "_all": {"enabled": false},
      "dynamic_date_formats": ["yyyy-MM-dd HH:mm:ss"]
    }
}

此时只有当字符串格式为"yyyy-MM-dd HH:mm:ss"才会被自动识别为日期类型,并且format就是被识别的格式.

使用 dynamic_templates,你可以完全控制新字段的映射,你设置可以通过字段名或数据类型应用一个完全不同的映射。

PUT /my_index
{
    "mappings": {
        "my_type": {
            "dynamic_templates": [
                { "en": {
                      "match":              "*_en", 
                      "match_mapping_type": "string",
                      "mapping": {
                          "type":           "string",
                          "analyzer":       "english"
                      }
                }},
                { "not_analyzed": {
                      "match":              "*", 
                      "match_mapping_type": "string",
                      "mapping": {
                          "type":           "string",
                          "index":       "not_analyzed"
                      }
                }}
            ]
        }

    }

}

上面的dynamic_templates实现了将以"_en"结尾且类型为string的字段映射为使用“english”分析器的类型,其余的映射为不索引字段

倒排索引

在了解分析的概念前,先要简单了解一下什么是倒排索引

倒排索引(inverted index)的结构是ES用来做快速的全文搜索的。倒排索引由在文档中出现的唯一的单词列表,以及对于每个单词在文档中的位置组成。

例如,我们有两个文档,每个文档content字段包含:

  1. dog cat bird
  2. dog girl boy

把它放到倒排索引中的结果如下:

 term  Doc_1  Doc_2
 dog  X  X
 cat  X  
 bird  X  
 girl    X
 boy    X

当需要查找dog bird时,只需要在索引中查找,如下:

 term  Doc_1  Doc_2
 dog  X  X
 bird  X  
 total  2  1

两个文档都匹配,但是第一个比第二个有更多的匹配项。以此就可以轻易的看到Doc_1的匹配度高于Doc_2的匹配度

当然实际应用中要复杂的多,比如索引中还会保存字符出现的次数和出现的位置,一个长度长的词还会比一个短的词在匹配度计算时占更高的分值等。

实际应用场景中我们还会遇到一些问题:

  • 大小写不敏感
  • 近义词、复数
  • 中文如何进行分词

下面会继续讲解对这些情况处理

分析

分析(analysis)是这样一个过程:

  • 首先,标记化一个文本块为适用于倒排索引单独的词(term)
  • 然后标准化这些词为标准形式,提高它们的“可搜索性”或“查全率”

分析的过程如下图:

QQ图片20170412162825.png

  • 字符过滤器(character filter)

首先字符串经过字符过滤器,它们的工作是在标记化前处理字符串。字符过滤器能够去除HTML标记,或者转换"&"为"and"。

  • 分词器(tokenizer)

分词器被标记化成独立的词。一个简单的分词器(tokenizer)可以根据空格或逗号将单词分开(这个在中文中不适用)。

  • 标记过滤(token filters)

标记过滤可以修改词(例如将"Quick"转为小写),去掉词(例如停用词像"a"、"and"、"the"等等),或者增加词(例如同义词像"jump"和"leap")

由上面的图可以看出:Analyzer(分析器)由Tokenizer(分词器)和Filter(过滤器)组成。

常用的分析器有:

  • standard analyzer:标准分析器
  • simple analyzer:简单分析器,包含lower case tokenizer
  • language analyzers:各语言的分词器
  • 自定义分词器:可以指定一个tokenizer,0个、1个或多个Filter

在mapping中指定分析器

    "field1" : {
        "type" : "string",
        "analyzer" : "string_lowercase"
    }

}

指定默认的分析器

 {

    "field1" : {
        "type" : "string"
    }

}

不使用分析器

    "field1" : {
        "type" : "string",
        "index" : "not_analyzed"
    }

}

本人用的是英文分词器:如下:

参考文档:

ES中的分词器

Elasticsearch权威指南(中文版)

猜你喜欢

转载自blog.csdn.net/winy_lm/article/details/79802765
今日推荐