转自: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] <- lookupRequest } 

这里是否可以进行优化? 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)方法。其主要逻辑如下:

  1. 将分词和标签合并在一起进行搜索
  2. 合并搜索到的docId,并进行初步排序,将docId大的排在前面(实际上是认为docId越大,时间越近,时效性越好)
  3. 然后进行排序,BM25算法
  4. 最后返回数据

转载于:https://www.cnblogs.com/bonelee/p/6341334.html

悟空分词的搜索和排序源码分析之——搜索相关推荐

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

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

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

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

  3. wukong引擎源码分析之搜索——docid有序的数组里二分归并求交集,如果用跳表的话,在插入索引时会更快...

    searcher.Search(types.SearchRequest{Text: "百度中国"}) // 查找满足搜索条件的文档,此函数线程安全 func (engine *En ...

  4. lucene 7.x 分词 TokenStream的使用及源码分析

    一.使用步骤 1 //将一个字符串创建成token流,第一个参数---fiedName,是一种标志性参数,可以写空字符串,不建议用null,因为null对于IKAnalyzer会包错 2 TokenS ...

  5. 分享88个搜索链接PHP源码,总有一款适合你

    PHP搜索链接源码 分享88个搜索链接PHP源码,总有一款适合你 链接:https://pan.baidu.com/s/1blE9zIxqA2_0ZVLiYUW4Zw  提取码:758j 下面是文件的 ...

  6. ictclas4j java_ictclas4j 中科院中文分词系统完成的java源码,能很好的实现 的 ,为文本挖掘提供基础。 Develop 238万源代码下载- www.pudn.com...

    文件名称: ictclas4j下载 收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 6617 KB 上传时间: 2013-12-06 下载次数: 4 提 供 者: 黄倩 ...

  7. 百度相关搜索软件_Python与seo,百度关键词相关搜索关键词采集源码

    百度关键词相关搜索关键词采集源码 瞎写的,看看就好! #百度相关搜索# -*- coding=utf-8 -*-#20200714 by 微信:huguo00289import requests,ti ...

  8. C++Breadth First Search 广度优先搜索(附完整源码)

    C++Breadth First Search 广度优先搜索的实现 C++Breadth First Search 广度优先搜索实现完整源码(定义,实现,main函数测试) C++Breadth Fi ...

  9. 抖音SEO优化源码,企业号搜索排名系统,矩阵同步分发。

    前言:抖音SEO优化源码,企业号搜索排名系统,矩阵同步分发. 抖音seo源码如何搭建?抖音seo排名优化系统软件部分源码分析,代码打包中... 场景:在 python 中,你可以使用 list[10: ...

最新文章

  1. 分布式实时日志分析解决方案ELK部署架构
  2. 一键清除bios密码_电脑忘记开机密码?怎么才能开机使用
  3. typedefnbsp;struct与struct的区别
  4. 白话详细解读(二)-----AlexNet
  5. 温州大学《机器学习》课程课件(九、支持向量机)
  6. beego数据库orm操作数据表返回数组
  7. FL的萌新之路,开始了!
  8. android的app语言无法切换,Android应用实现多语言切换
  9. js设置控件的隐藏与显示的两种方法
  10. 编程语言对比 导入模块
  11. 【Python系列】之画BD-RATE及码率波动图示例
  12. Redis入门指南--五种类型及其基本指令
  13. 内置模块--又称为常用模块
  14. NOIP2001题目汇总
  15. HDU 4968(杭电多校#9 1009题)Improving the GPA (瞎搞)
  16. openstack-o版-启动实例
  17. 文章整理 - 匠人精神
  18. 时间序列 ARMA 模型实战!
  19. 左程云算法笔记(三)堆排序、桶排序、排序总结
  20. 这种网站我看见就收藏

热门文章

  1. Linux下挂载与解除挂载U盘
  2. bootstrap的php写在哪里,bootstrap用什么编辑器写
  3. 适合手机运行的服务器系统,一台服务器能维持多久?谈谈服务器的运行寿命
  4. php中ini set,php ini_set更改php.ini配置功能
  5. 乌鲁木齐计算机老师待遇,如果月薪超过10000元,安排去新疆当教学教师,愿意吗?...
  6. Java单例模式代码实现方式
  7. java读取pdf文件流,系列篇
  8. 【PAT (Advanced Level) Practice】1037 Magic Coupon (25 分)
  9. linux查询python的进程树_如何在Linux中查看所有正在运行的进程
  10. mysql mydumper_mysql数据库备份之mydumper