转自:http://blog.codeg.cn/2016/02/02/wukong-source-code-reading/

搜索过程分析

下面我们来分析一下搜索的过程。首先构造一个SearchRequest对象。一般情况下只需提供SearchRequest.Text即可。

type SearchRequest struct {

// 搜索的短语(必须是UTF-8格式),会被分词

// 当值为空字符串时关键词会从下面的Tokens读入

Text string

// 关键词(必须是UTF-8格式),当Text不为空时优先使用Text

// 通常你不需要自己指定关键词,除非你运行自己的分词程序

Tokens []string

// 文档标签(必须是UTF-8格式),标签不存在文档文本中,但也属于搜索键的一种

Labels []string

// 当不为nil时,仅从这些DocIds包含的键中搜索(忽略值)

DocIds map[uint64]bool

// 排序选项

RankOptions *RankOptions

// 超时,单位毫秒(千分之一秒)。此值小于等于零时不设超时。

// 搜索超时的情况下仍有可能返回部分排序结果。

Timeout int

// 设为true时仅统计搜索到的文档个数,不返回具体的文档

CountDocsOnly bool

// 不排序,对于可在引擎外部(比如客户端)排序情况适用

// 对返回文档很多的情况打开此选项可以有效节省时间

Orderless bool

}

从本文一开始那段示例代码的搜索语句读起:searcher.Search(types.SearchRequest{Text:"百度中国"})。进入到 Search 函数内部,其逻辑如下:

设置一些搜索选项

例如排序选项RankOptions, 分数计算条件ScoringCriteria等等

将搜索词进行分词

// 收集关键词

tokens := []string{}

if request.Text != "" {

querySegments := engine.segmenter.Segment([]byte(request.Text))

for _, s := range querySegments {

token := s.Token().Text()

if !engine.stopTokens.IsStopToken(token) {

tokens = append(tokens, s.Token().Text())

}

}

} else {

for _, t := range request.Tokens {

tokens = append(tokens, t)

}

}

这里的”百度中国”会分词得到两个词:百度 和中国

向索引器发送查找请求

// 建立排序器返回的通信通道

rankerReturnChannel := make(

chan rankerReturnRequest, engine.initOptions.NumShards)

// 生成查找请求

lookupRequest := indexerLookupRequest{

countDocsOnly: request.CountDocsOnly,

tokens: tokens,

labels: request.Labels,

docIds: request.DocIds,

options: rankOptions,

rankerReturnChannel: rankerReturnChannel,

orderless: request.Orderless,

}

// 向索引器发送查找请求

for shard := 0; shard < engine.initOptions.NumShards; shard++ {

engine.indexerLookupChannels[shard]

}

这里是否可以进行优化? 1) 只向特定的shard分发请求,避免无谓的indexer查找过程。2)rankerReturnChannel是否不用每次都创建新的?

读取索引器的返回结果然后排序

上面已经建立了结果的返回通道rankerReturnChannel,直接从个channel中读取返回数据,并加入到数组rankOutput中。 注意,如果设置了超时,就在超时之前能读取多少就读多少。 然后调用排序算法进行排序。排序算法直接调用Golang自带的sort包的排序算法。

下面我们深入到索引器,看看索引器是如何进行搜索的。其核心代码在这里func (engine *Engine) indexerLookupWorker(shard int),它的主逻辑是一个死循环,不断的从engine.indexerLookupChannels[shard]读取搜索请求。

针对每一个搜索请求,会将请求分发到索引器去,调用func (indexer *Indexer) Lookup(tokens []string, labels []string, docIds map[uint64]bool, countDocsOnly bool) (docs []types.IndexedDocument, numDocs int)方法。其主要逻辑如下:

将分词和标签合并在一起进行搜索

合并搜索到的docId,并进行初步排序,将docId大的排在前面(实际上是认为docId越大,时间越近,时效性越好)

然后进行排序,BM25算法

最后返回数据

悟空分词与mysql结合_悟空分词的搜索和排序源码分析之——搜索相关推荐

  1. 悟空分词与mysql结合_悟空分词的搜索和排序源码分析之——索引

    转自:http://blog.codeg.cn/2016/02/02/wukong-source-code-reading/ 索引过程分析 下面我们来分析索引过程. // 将文档加入索引 // // ...

  2. 悟空分词的搜索和排序源码分析之——搜索

    转自:http://blog.codeg.cn/2016/02/02/wukong-source-code-reading/ 搜索过程分析 下面我们来分析一下搜索的过程.首先构造一个SearchReq ...

  3. springboot 事务_原创002 | 搭上SpringBoot事务源码分析专车

    前言 如果这是你第二次看到师长,说明你在觊觎我的美色! 点赞+关注再看,养成习惯 没别的意思,就是需要你的窥屏^_^ 专车介绍 该趟专车是开往Spring Boot事务源码分析的专车 专车问题 为什么 ...

  4. 悟空分词与mysql结合_中文分词与关键词提取实践小结

    本文基于题库查重需求实现过程及<NLP自然语言处理原理与实践>学习过程总结得出.定有不足之处,恳请指出. 基本概念 评价指标 一般,中文分词从Precision.Recall.F-scor ...

  5. mysql朗读_“绘爱”诗词朗读小程序源码(thinkphp+mysql+小程序端)

    两年前,写了个这个"ThinkPHP开发微信语音小程序",时隔2年,小程序框架发展的也是日新月异.前段时间因为开发app,偶然接触到了dcloud的uni-app框架,真的是爽的不 ...

  6. java tomcat源码_详解Tomcat系列(一)-从源码分析Tomcat的启动

    在整个Tomcat系列文章讲解之前, 我想说的是虽然整个Tomcat体系比较复杂, 但是Tomcat中的代码并不难读, 只要认真花点功夫, 一定能啃下来. 由于篇幅的原因, 很难把Tomcat所有的知 ...

  7. java ee是什么_死磕 java集合之HashSet源码分析

    问题 (1)集合(Collection)和集合(Set)有什么区别? (2)HashSet怎么保证添加元素不重复? (3)HashSet是否允许null元素? (4)HashSet是有序的吗? (5) ...

  8. hashmap修改对应key的值_死磕 java集合之HashMap源码分析

    简介 HashMap采用key/value存储结构,每个key对应唯一的value,查询和修改的速度都很快,能达到O(1)的平均时间复杂度.它是非线程安全的,且不保证元素存储的顺序: 继承体系 Has ...

  9. 结巴分词关键词相似度_结巴分词5--关键词抽取

    作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 简介 关键词抽取就是从文本里面把跟这篇文档意义最相关的一些词抽 ...

最新文章

  1. django 数据库迁移注意事项
  2. 服务器开好服怎么和网站连,vps开服连服务器没反应
  3. python数据库操作之pymysql模块和sqlalchemy模块(项目必备)
  4. 运行GPU出现CUDA_ERROR_LAUNCH_FAILED
  5. 基于360搜图爬取图片
  6. cv::cornerSubPix()亚像素角点检测
  7. 9. explain
  8. Java的 类型转换器工具类Convert
  9. CrossOver Mac2022双系统虚拟机软件
  10. journey、voyage、trip、tour、travel的用法区别
  11. python学习总结报告第一期
  12. C语言 简易计算器 //支持求阶乘
  13. 利用DirectShow开发C#版的MP3播放器(一)
  14. 学3d建模和计算机编程,超好用的3D建模软件全科普,想要学好建模的你千万别错过!...
  15. nslookup参数说明
  16. N次笑N次据说可以让人年轻10岁的故事
  17. Win7使用技巧(持续更新...)
  18. 标贝科技登全球语音大赛舞台Blizzard Challenge做精彩开场发言
  19. 2019新媒体的趋势和玩法
  20. Keil uvision5 C51软件安装教程附下载地址

热门文章

  1. python抓取视频违法吗,科学网—【python爬虫】抓取B站视频相关信息(一) - 管金昱的博文...
  2. UsbAccessory和UsbDevice的区别
  3. CSS3JavaScript 电池充电
  4. 模型泛化技巧“随机权重平均(Stochastic Weight Averaging, SWA)”介绍与Pytorch Lightning的SWA实现讲解
  5. codechef October Challenge 2017解题报告
  6. 每周推荐短视频:企业学校与用户如何参与开源生态建设?
  7. 整体大于部分_格式塔心理咨询与治疗技术之争议话题:“整体大于部分之和”...
  8. Meego系统全面解析(初始化)
  9. CKPT,DBWn,LGWR
  10. 利用Wolfram Alpha解决数学,金融,物理等应用问题用法举例