搜索的一般过程

  之前学习过很多刘老师的lucene源码分析的课程,结果现在整的都忘了,这次重新梳理一下争取形成自己的东西。
后面就不容易忘掉了。
  刘老师的课程是基于lucene2.x的源码分析的,后面lucene迭代了很多版本,也引入了新的数据结构进行优化,但是主体的模块基本上是没有变的。计划是先把之前的lunce的数据结构整理一下,因为可以查阅刘老师的课程,可以有很好的参考作用。在这个基础上再整理和对比新的lucene的优化点,基于lucene7.x在这里主要关注lucene的存储结构,因为了解了存储结构基本上就了解了大体的实现。

1. 搜索的概览

搜索主要是解决用户基于文本进行搜索的问题。比如在很多本书中搜索一些内容,或者搜索一些帖子,博客等等。
一个搜索服务架构分为两大部分:索引+搜索。

1.1 索引

索引的过程又分为数据采集,清洗,进入lucene等等,这里我们不关注数据源的问题,只关注索引在进入lucene会有哪些操作。

1.1.1. 数据处理

在往lucene进行数据存储的时候首先会进行分词,比如"我的家乡是河南","this ARE GOOD books " 在下面显示了对应的分词结果

GET user/_analyze
{
  "analyzer": "ik_smart",
  "text": ["我的家乡是河南"]
}

对应的分词结果是
{
  "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" : 4,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "是",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "CN_CHAR",
      "position" : 3
    },
    {
      "token" : "河南",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 4
    }
  ]
}


再来一个英文的

GET user/_analyze
{
  "analyzer": "ik_smart",
  "text": ["this ARE GOOD books "]
}

{
  "tokens" : [
    {
      "token" : "good",
      "start_offset" : 9,
      "end_offset" : 13,
      "type" : "ENGLISH",
      "position" : 0
    },
    {
      "token" : "books",
      "start_offset" : 14,
      "end_offset" : 19,
      "type" : "ENGLISH",
      "position" : 1
    }
  ]
}

对应的可以看到,一个句子被分成了多个词,同时可能会有一些转化,比如大写变小写,复数变单数等。
其实analyzer又有三个部分组成

  1. character_filter 对输入文档的源数据进行处理,比如将拉丁文转为数字等,也可以是删掉一些字符
  2. tokenizer 对character_filter 过滤后的文档进行分词,会记录词的位置信息以及字符偏移量
  3. token_filter 对分出来的词进行处理,比如大写转小写,词干抽取等。

词干抽取被称为stemming,方式也分为两种,基于算法的词干抽取和基于字典的词干抽取。
基于算法有可能会导致不准确的结果,但是只要index 和 query的过程都使用同样的算法,那么就可以保证搜索效果的一致性。
基于字典的词干抽取的效果则取决于字典的质量,而且大量的字典可能会占据比较大的内存。

1.1.2. 数据存储

在一个文档进行了分词,词干提取等处理之后,会交给indexer,由indexer来进行存储。
存储一般包括两个部分,索引的正向信息,和反向信息,
正向信息是指从index–>segment—>doc-field—>field-terms 的信息,这里存储的基本上是文档的正向信息,也是完整信息。
反向信息就是我们常说的倒排索引了 terms—>doc-list 通过对terms的命中可以快速的找到对应的doc信息。

1.2 查询search

query样例 用户输入语句:lucene AND learned NOT hadoop。

1.2.1. 语法分析

查询语句又会有一些语法,类似sql一样,必有有or,and,not等语法,所以先要进行这些语法分析,识别这些关键字
提取了两个关键字 AND NOT

1.2.2. 词分析

和index的时候对此的操作是一致的
上面会产生三个term lucene learned hadoop

1.2.3 搜索搜因得到文档
  1. 根据前面两步得到了查询的逻辑以及对应的term
  2. 从倒排链表中找到对应的文档集合,得到3个文档集合
  3. 对lucene和learned对应的两个文档集合求交集,然后和hadoop的文档集合求差集。
1.2.4 进行相关性分析,根据相关性打分进行排序,并返回结果

相关性得分计算有一些公开的比较成熟的方案,比如之前的tf/idf,现在的BM25打分公式等。

上面就是搜索是两大模块式 index,search的主体流程,后面我们逐渐深入lucene的数据结构。

·

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值