wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用
之前的文章分析过,接受索引请求处理的代码在segmenter_worker.go里:
func (engine *Engine) segmenterWorker() {
for {
request := <-engine.segmenterChannel //关键 tokensMap := make(map[string][]int)
numTokens := 0
if !engine.initOptions.NotUsingSegmenter && request.data.Content != "" {
// 当文档正文不为空时,优先从内容分词中得到关键词
segments := engine.segmenter.Segment([]byte(request.data.Content))
for _, segment := range segments {
token := segment.Token().Text()
if !engine.stopTokens.IsStopToken(token) {
tokensMap[token] = append(tokensMap[token], segment.Start())
}
}
numTokens = len(segments)
} else {
// 否则载入用户输入的关键词
for _, t := range request.data.Tokens {
if !engine.stopTokens.IsStopToken(t.Text) {
tokensMap[t.Text] = t.Locations
}
}
numTokens = len(request.data.Tokens)
} // 加入非分词的文档标签
for _, label := range request.data.Labels {
if !engine.initOptions.NotUsingSegmenter {
if !engine.stopTokens.IsStopToken(label) {
tokensMap[label] = []int{}
}
} else {
tokensMap[label] = []int{}
}
} indexerRequest := indexerAddDocumentRequest{
document: &types.DocumentIndex{
DocId: request.docId,
TokenLength: float32(numTokens),
Keywords: make([]types.KeywordIndex, len(tokensMap)),
},
}
iTokens := 0
for k, v := range tokensMap {
indexerRequest.document.Keywords[iTokens] = types.KeywordIndex{
Text: k,
// 非分词标注的词频设置为0,不参与tf-idf计算
Frequency: float32(len(v)),
Starts: v}
iTokens++
} var dealDocInfoChan = make(chan bool, 1) indexerRequest.dealDocInfoChan = dealDocInfoChan
engine.indexerAddDocumentChannels[request.shard] <- indexerRequest rankerRequest := rankerAddDocRequest{
docId: request.docId,
fields: request.data.Fields,
dealDocInfoChan: dealDocInfoChan,
}
engine.rankerAddDocChannels[request.shard] <- rankerRequest
}
}
上面代码的作用就是在统计词频和单词位置(注意:tag也是作为搜索的单词,不过其词频是0,而无法参与tf-idf计算),并封装为indexerRequest,发送给engine.indexerAddDocumentChannels[request.shard]
此外,红色部分代码是在为文档评分做准备,engine/ranker_worker.go:
func (engine *Engine) rankerAddDocWorker(shard int) {
for {
request := <-engine.rankerAddDocChannels[shard] //关键
docInfo := engine.rankers[shard].AddDoc(request.docId, request.fields, request.dealDocInfoChan)
// save
if engine.initOptions.UsePersistentStorage {
engine.persistentStorageIndexDocumentChannels[shard] <- persistentStorageIndexDocumentRequest{
typ: "info",
docId: request.docId,
docInfo: docInfo,
}
}
}
}
AddDoc无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用!
// 给某个文档添加评分字段
func (ranker *Ranker) AddDoc(docId uint64, fields interface{}, dealDocInfoChan <-chan bool) *types.DocInfo {
if ranker.initialized == false {
log.Fatal("排序器尚未初始化")
} <-dealDocInfoChan // 等待索引器处理完成 ranker.DocInfosShard.Lock()
defer ranker.DocInfosShard.Unlock()
if _, found := ranker.DocInfosShard.DocInfos[docId]; !found {
ranker.DocInfosShard.DocInfos[docId] = new(types.DocInfo)
ranker.DocInfosShard.NumDocuments++
}
ranker.DocInfosShard.DocInfos[docId].Fields = fields
return ranker.DocInfosShard.DocInfos[docId]
}
wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用的更多相关文章
- wukong引擎源码分析之索引——part 2 持久化 直接set(key,docID数组)在kv存储里
前面说过,接收indexerRequest的代码在index_worker.go里: func (engine *Engine) indexerAddDocumentWorker(shard int) ...
- wukong引擎源码分析之索引——part 1 倒排列表本质是有序数组存储
searcher.IndexDocument(0, types.DocumentIndexData{Content: "此次百度收购将成中国互联网最大并购"}) engine.go ...
- wukong引擎源码分析之搜索——docid有序的数组里二分归并求交集,如果用跳表的话,在插入索引时会更快
searcher.Search(types.SearchRequest{Text: "百度中国"}) // 查找满足搜索条件的文档,此函数线程安全 func (engine *En ...
- Spark源码分析 – 汇总索引
http://jerryshao.me/categories.html#architecture-ref http://blog.csdn.net/pelick/article/details/172 ...
- 源码分析 Kafka 消息发送流程(文末附流程图)
温馨提示:本文基于 Kafka 2.2.1 版本.本文主要是以源码的手段一步一步探究消息发送流程,如果对源码不感兴趣,可以直接跳到文末查看消息发送流程图与消息发送本地缓存存储结构. 从上文 初识 Ka ...
- 转:Irrlicht 0.1引擎源码分析与研究(一)
目录(?)[-] 主要技术特性 引擎概览 Irrlicht的窗口管理 Irrlicht引擎主要是由一个名叫Nikolaus Gebhardt奥地利人所设计,是sourceforge上的一个开源项目 ...
- bleve搜索引擎源码分析之索引——mapping真复杂啊
接下来看看下面index部分的源码实现: data := struct { Name string Des string }{ Name: "hello world this is bone ...
- bleve搜索引擎源码分析之索引——mapping和lucene一样,也有_all
例子: package main import ( "fmt" "github.com/blevesearch/bleve" ) func main() { / ...
- lua源码分析 伪索引
Lua 提供了一个 注册表, 这是一个预定义出来的表, 可以用来保存任何 C 代码想保存的 Lua 值. 这个表可以用有效伪索引 LUA_REGISTRYINDEX 来定位. 任何 C 库都可以在这张 ...
随机推荐
- PHP输出控制函数(ob系列函数)
PHP输出控制函数(ob系列函数) flush — 刷新输出缓冲ob_clean — 清空(擦掉)输出缓冲区ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲ob_end_flush — ...
- hdu - 3594 Cactus (强连通)
http://acm.hdu.edu.cn/showproblem.php?pid=3594 判断给定的图是否是强连通的,并且每条边都只属于一个连通分量. 判断强连通只需要判断缩点之后顶点数是否为1即 ...
- luogu P2085 最小函数值
题目描述 有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个 ...
- Java中获取项目根路径和类加载路径的7种方法
引言 在web项目开发过程中,可能会经常遇到要获取项目根路径的情况,那接下来我就总结一下,java中获取项目根路径的7种方法,主要是通过thisClass和System,线程和request等方法. ...
- Python知识图谱
一.Python全栈图谱 2.Python语言高级 Python 全栈工程师前端 Python全栈工程师后端 Python Linux运维自动化开发 Python KaliLinux信息安全开发和使用 ...
- php 笔记 汇总 学习
php命令行:通过命令行进入到当前要被执行的php文件路径,然后输入php环境可执行路径(后面包含php.exe),然后输入要被执行的php文件,比如runData.php即可. php框架:yaf. ...
- UICollectionView 使用 介绍
1.1. Collection View 全家福: UICollectionView, UITableView, NSCollectionView n 不直接等效于NSCollectionView ...
- 基于MNIST数据的softmax regression
跟着tensorflow上mnist基本机器学习教程联系 首先了解sklearn接口: sklearn.linear_model.LogisticRegression In the multiclas ...
- Python 一行命令ftp服务器
Obligatory Twisted example: twistd -n ftp And probably useful: twistd ftp --help Usage: twistd [opti ...
- pcapReader——源代码分析
一.简单介绍 pcapReader是ndpi开源中的一个example. 大家能够从<ndpi directory>/example/pcapReader.c中找到它的源码.通过pcapl ...