ELK之倒排索引

倒排索引的建立过程
倒排索引是搜索引擎中常见的索引方法,用来存储在全文搜索下某个单词在一个文档中存储位置的映射。通过倒排索引,我们输入一个关键词,可以非常快地获取包含这个关键词的文档列表。

我们先看英文的,假设我们有两个文档:

I have a friend who loves smile
love me, I love you
为了建立倒排索引,我们先按最简单的用空格把每个单词分开,可以得到如下结果:
*表示该列文档中有这个词条,为空表示没有该词条

Term doc1 doc2
I * *
have *
a *
friend *
who *
loves *
smile *
love *
me *
you *
如果我们要搜索 I love you,我们只需要查找包含每个词条的文档:

Term doc1 doc2
I * *
love *
you *
两个文档都能匹配上,如果按命中词条数量来算,doc2比doc1更匹配。

这个是倒排索引最简化的表达方式,在ES的倒排索引存储结果中,还会记录每个词条在文档中出现的位置。

期望的分词处理
我们再看一下这个索引的建立过程,loves和love有区别吗?没有,都是爱的意思,一个是第三人称单数,一个是原形。如果能将一些语法的区别处理掉,这样的搜索结果是不是更切合实际需求?
例如:

loves提取词干处理成love
a,have之类的无实义的词,直接屏蔽掉
等等
现在索引看上去成这样:

Term doc1 doc2
friend *
love * *
smile *
me *
you *
这样是不是精简了很多?
这个过程叫normalization,在建立倒排索引的时候,会执行一系列的操作,对拆分出的各个单词进行相应的处理,以提升后面搜索的时候能够搜索到相关联的文档的概率,如时态的转换,单复数的转换,同义词的转换,大小写的转换等。

分词器登场
分词器的作用就是把整篇文档,按一定的语义切分成一个一个的词条,目标是提升文档的召回率,并降低无效数据的噪音。

recall召回率,也叫可搜索性,指搜索的时候,增加能够搜索到的结果的数量。
降噪:指降低文档中一些低相关性词条对整体搜索排序结果的干扰。

文档的分词过程包含以下几步:

字符过滤器
对字符串进行预处理,如HTML标签清洗Love --> Love,I & you --> I and you等等。

分词器
把字符串切分成单个的词条,如英文的按空格和标点切分,中文的按词语切分,针对不同的语言,有不同的分词器,有相对简单的标准分词器,也有特别复杂的中文分词器,里面包含了非常复杂的切分逻辑如:

I Love you --> I/Love/you

我和我的祖国 --> 我/和/我的/祖国

Token过滤器

将分词器得到的词条进一步的处理,如改变词条(英文词干提取loves --> love),删除无实际意义的词条(英文的a, and, this,中文的"的",“了”,“吗”),增加词条(补充同义词)
分词器非常重要,好的分词器可以显著提升召回率,不恰当的分词器得到的结果可能会对搜索产生歧义,最后处理好的结果再拿去建立倒排索引。

常见分词器介绍

Elasticsearch自身提供了内置的分词器,也允许使用第三方的分词器。

内置分词器
标准分词器standard analyzer
ES默认分词器,根据Unicode联盟定义的单词边界划分文本,删除绝大部分标点,最后将词条小写。

简单分词器simple analyzer
在任何不是字母的地方分隔文本,将词条小写

空格分词器whitespace analyzer
在空格的地方划分文本

语言分词器language analyzer
特定的语言的分词器,如english,英语分词器,维护了一组英语停用词and、the之类的,用于删除词条,针对英文语法规则,有提取单词词干的能力。

内置的分词器主要是对英文的支持效果比较好,中文则需要使用外部的分词器。

外部分词器
IK中文分词器ik_max_word
会将文本做最细粒度的拆分;尽可能多的拆分出词语。
如南京市长江大桥 --> 南京市/南京/市长/长江大桥/长江/大桥

IK中文分词器ik_smart
会做最粗粒度的拆分;已被分出的词语将不会再次被其它词语占有
如南京市长江大桥 --> 南京市/长江大桥

中日韩文分词器cjk
支持亚洲语言中文,日文,韩文
如南京市长江大桥 --> 南京/京市/市长/长江/江大/大桥

阿里中文分词器aliws
阿里自研的中文分词器
如南京市长江大桥 --> 南京/市/长江/大桥

外部分词器众多,开源也有很多,有针对不同语言,不同领域的,各位可以结合自身业务的特点,挑选适合自己的分词器,这里就不一一介绍了,有兴趣自己可以去了解一下。

测试分词效果

ES有analyze API来查看文本是如何被分词的,可用来做学习和调试用,请求命令如下:

GET /_analyze
{
  "analyzer": "ik_max_word",
  "text": "南京市长江大桥"
}

响应结果:

{
  "tokens": [
    {
      "token": "南京市",
      "start_offset": 0,
      "end_offset": 3,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "南京",
      "start_offset": 0,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 1
    },
    {
      "token": "市长",
      "start_offset": 2,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 2
    },
    {
      "token": "长江大桥",
      "start_offset": 3,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 3
    },
    {
      "token": "长江",
      "start_offset": 3,
      "end_offset": 5,
      "type": "CN_WORD",
      "position": 4
    },
    {
      "token": "大桥",
      "start_offset": 5,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 5
    }
  ]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缘不易

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值