ES系列--分析器

一、前言

ES进行文档分析就会涉及到分析器,无论是内置的分析器,还是自定义的分析器,都是由一个分词器(tokenizers) 、0或多个词项过滤器(token filters)、0或多个字符过滤器(character filters)组成。

二、内置分析器 

Elasticsearch 还附带了可以直接使用的预包装的分析器。以下会用

"Set the shape to semi-transparent by calling set_trans(5)" 这段字符串对内置的各种分析器进行区分。

 一、标准分析器

标准分析器是 Elasticsearch 默认使用的分析器。它是分析各种语言文本最常用的选择。 它根据 Unicode 联盟定义的单词边界划分文本,删除绝大部分标点。最后,将词条小写。 它会产生:

set, the, shape, to, semi, transparent, by, calling, set_trans, 5

二、简单分析器 

简单分析器在任何不是字母的地方分隔文本,将词条小写。它会产生:

set, the, shape, to, semi, transparent, by, calling, set, trans

三、空格分析器 

空格分析器在空格的地方划分文本。它会产生:

Set, the, shape, to, semi-transparent, by, calling, set_trans(5)

四、语言分析器

特定语言分析器可用于 很多语言。它们可以考虑指定语言的特点。例如, 英语 分析 器附带了一组英语无用词(常用单词,例如 and 或者 the ,它们对相关性没有多少影响), 它们会被删除。 由于理解英语语法的规则,这个分词器可以提取英语单词的 词干 。

英语 分词器会产生下面的词条:

set, shape, semi, transpar, call, set_tran, 5

注意看 transparent、 calling 和 set_trans 已经变为词根格式

三、IK分词器

一、IK分词器测试

        当Elasticsearch在你的文档中检测到一个新的字符串域,它会自动设置其为一个全文 字 符串 域,使用 标准 分析器对它进行分析。你不希望总是这样。可能你想使用一个不同的 分析器,适用于你的数据使用的语言。有时候你想要一个字符串域就是一个字符串域—不使用分析,直接索引你传入的精确值,例如用户 ID 或者一个内部的状态域或标签。要做到这 一点,我们必须手动指定这些域的映射。

很多时候我们使用默认的分析器,是无法达到我们的需求的。例如:

 GET http://localhost:9200/_analyze

{

"text":"测试单词"

}

如果使用内置的分析器,会产生:

{
    "tokens": [{
            "token": "测",
            "start_offset": 0,
            "end_offset": 1,
            "type": "",
            "position": 0
        },
        {
            "token": "试",
            "start_offset": 1,
            "end_offset": 2,
            "type": "",
            "position": 1
        },
        {
            "token": "单",
            "start_offset": 2,
            "end_offset": 3,
            "type": "",
            "position": 2
        },
        {
            "token": "词",
            "start_offset": 3,
            "end_offset": 4,
            "type": "",
            "position": 3
        }
    ]
}

这是由于ES 的默认分词器无法识别中文中测试、单词这样的词汇,而是简单的将每个字拆完分为一 个词。这样的结果显然不符合我们的使用要求,所以我们需要下载 ES 对应版本的中文分词器。

IK 中文分词器地址:

https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.8.0 将解压后的后的文件夹放入 ES 根目录下的 plugins 目录下,重启 ES 即可使用。

1、ik_max_word:会将文本做最细粒度的拆分

2、ik_smart:会将文本做最粗粒度的拆分

我们这次加入新的查询参数"analyzer":"ik_max_word"

GET http://localhost:9200/_analyze

{

"text":"测试单词",

"analyzer":"ik_max_word"

}

{
    "tokens": [{
            "token": "测试",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "单词",
            "start_offset": 2,
            "end_offset": 4,
            "type": "CN_WORD",
            "position": 1
        }
    ]
}

二、IK分词器拓展

ES 中也可以进行扩展词汇,首先查询

GET http://localhost:9200/_analyze

{

"text":"弗雷尔卓德",

"analyzer":"ik_max_word"

}

{
    "tokens": [{
        "token": "弗",
        "start_offset": 0,
        "end_offset": 1,
        "type": "CN_CHAR",
        "position": 0
    }, {
        "token": "雷",
        "start_offset": 1,
        "end_offset": 2,
        "type": "CN_CHAR",
        "position": 1
    }, {
        "token": "尔",
        "start_offset": 2,
        "end_offset": 3,
        "type": "CN_CHAR",
        "position": 2
    }, {
        "token": "卓",
        "start_offset": 3,
        "end_offset": 4,
        "type": "CN_CHAR",
        "position": 3
    }, {
        "token": "德",
        "start_offset": 4,
        "end_offset": 5,
        "type": "CN_CHAR",
        "position": 4
    }]
}

仅仅可以得到每个字的分词结果,我们需要做的就是使分词器识别到弗雷尔卓德也是一个词 语

首先进入 ES 根目录中的 plugins 文件夹下的 ik 文件夹,进入 config 目录,创建 custom.dic 文件,写入弗雷尔卓德。同时打开 IKAnalyzer.cfg.xml 文件,将新建的 custom.dic 配置其中, 重启 ES 服务器。

ES系列--分析器_第1张图片

四、分析器使用场景 

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

1、当你查询一个全文域时,会对查询字符串应用相同的分析器,以产生正确的搜 索词条列表。

2、当你查询一个 精确值 域时,不会分析查询字符串,而是搜索你指定的精确值。

五、测试分析器 

有些时候很难理解分词的过程和实际被存储到索引中的词条,特别是你刚接触 Elasticsearch。为了理解发生了什么,你可以使用 analyze API 来看文本是如何被分析的。 在消息体里,指定分析器和要分析的文本

GET http://localhost:9200/_analyze

{

        "analyzer": "standard",

        "text": "Text to analyze"

}

结果中每个元素代表一个单独的词条:

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

token 是实际存储到索引中的词条。

position 指明词条在原始文本中出现的位置。

start_offset 和 end_offset 指明字符在原始字符串中的位置。

六、自定义分析器 

虽然 Elasticsearch 带有一些现成的分析器,然而在分析器上 Elasticsearch 真正的强大之 处在于,你可以通过在一个适合你的特定数据的设置之中组合字符过滤器、分词器、词汇单 元过滤器来创建自定义的分析器。一个 分析器 就是在一个包 里面组合了三种函数的一个包装器, 三种函数按照顺序被执行:

1、字符过滤器:

字符过滤器 用来 整理 一个尚未被分词的字符串。例如,如果我们的文本是 HTML 格 式的,它会包含像

或者这样的 HTML 标签,这些标签是我们不想索引的。我 们可以使用 html 清除 字符过滤器 来移除掉所有的 HTML 标签,并且像把 Á 转换 为相对应的 Unicode 字符 Á 这样,转换 HTML 实体。一个分析器可能有 0 个或者多个字符 过滤器。

2、分词器:

一个分析器 必须 有一个唯一的分词器。 分词器把字符串分解成单个词条或者词汇单 元。 标准 分析器里使用的 标准 分词器 把一个字符串根据单词边界分解成单个词条,并 且移除掉大部分的标点符号,然而还有其他不同行为的分词器存在。 例如, 关键词 分词器 完整地输出 接收到的同样的字符串,并不做任何分词。 空格分词器只根据空格分割文本 。正则分词器 根据匹配正则表达式来分割文本 。

3、词单元过滤器:

经过分词,作为结果的 词单元流 会按照指定的顺序通过指定的词单元过滤器 。 词单元过滤器可以修改、添加或者移除词单元。我们已经提到过 lowercase 和 stop 词过滤 器 ,但是在 Elasticsearch 里面还有很多可供选择的词单元过滤器。词干过滤器 把单词 遏 制 为 词干。 ascii_folding 过滤器移除变音符,把一个像 "très" 这样的词转换为 "tres"。ngram 和 edge_ngram 词单元过滤器 可以产生 适合用于部分匹配或者自动补全的词单元。 

创建自定义的分析器 :

PUT http://localhost:9200/my_index

{
    "settings": {
        "analysis": {
            "char_filter": { // 字符串过滤器
                "&_to_and": {
                    "type": "mapping",
                    "mappings": ["&=> and "] // 将& 转换为 and
                }
            },
            "filter": {
                "my_stopwords": {
                    "type": "stop",
                    "stopwords": ["the", "a"]
                }
            },
            "analyzer": {
                "my_analyzer": {
                    "type": "custom",
                    "char_filter": ["html_strip", "&_to_and"],
                    "tokenizer": "standard",
                    "filter": ["lowercase", "my_stopwords"]
                }
            }
        }
    }
}

结果:

{
    "tokens": [{
            "token": "quick",
            "start_offset": 4,
            "end_offset": 9,
            "type": "",
            "position": 1
        },
        {
            "token": "and",
            "start_offset": 10,
            "end_offset": 11,
            "type": "",
            "position": 2
        },
        {
            "token": "brown",
            "start_offset": 12,
            "end_offset": 17,
            "type": "",
            "position": 3
        },
        {
            "token": "fox",
            "start_offset": 18,
            "end_offset": 21,
            "type": "",
            "position": 4
        }
    ]
}

你可能感兴趣的:(ElastricSearch,elasticsearch,搜索引擎)