segmenter_worker.go
package engine
import (
"github.com/huichen/wukong/types"
)
type segmenterRequest struct {
docId uint64
hash uint32
data types.DocumentIndexData
forceUpdate bool
}
func (engine *Engine) segmenterWorker() {
for {
request := <-engine.segmenterChannel
if request.docId == 0 {
if request.forceUpdate {
for i := 0; i < engine.initOptions.NumShards; i++ {
engine.indexerAddDocChannels[i] <- indexerAddDocumentRequest{forceUpdate: true}
}
}
continue
}
shard := engine.getShard(request.hash)
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) {
//当正文中已存在关键字时,若不判断,位置信息将会丢失
if _, ok := tokensMap[label]; !ok {
tokensMap[label] = []int{}
}
}
} else {
//当正文中已存在关键字时,若不判断,位置信息将会丢失
if _, ok := tokensMap[label]; !ok {
tokensMap[label] = []int{}
}
}
}
indexerRequest := indexerAddDocumentRequest{
document: &types.DocumentIndex{
DocId: request.docId,
TokenLength: float32(numTokens),
Keywords: make([]types.KeywordIndex, len(tokensMap)),
},
forceUpdate: request.forceUpdate,
}
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++
}
engine.indexerAddDocChannels[shard] <- indexerRequest
if request.forceUpdate {
for i := 0; i < engine.initOptions.NumShards; i++ {
if i == shard {
continue
}
engine.indexerAddDocChannels[i] <- indexerAddDocumentRequest{forceUpdate: true}
}
}
rankerRequest := rankerAddDocRequest{
docId: request.docId, fields: request.data.Fields}
engine.rankerAddDocChannels[shard] <- rankerRequest
}
}
segmenter_worker.go的更多相关文章
- wukong引擎源码分析之索引——part 1 倒排列表本质是有序数组存储
searcher.IndexDocument(0, types.DocumentIndexData{Content: "此次百度收购将成中国互联网最大并购"}) engine.go ...
- wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用
之前的文章分析过,接受索引请求处理的代码在segmenter_worker.go里: func (engine *Engine) segmenterWorker() { for { request : ...
随机推荐
- LeetCode(43)-Contains Duplicate II
题目: Given an array of integers and an integer k, find out whether there are two distinct indices i a ...
- python MultiProcessing模块进程间通信的解惑与回顾
这段时间沉迷MultiProcessing模块不能自拔,没办法,python的基础不太熟,因此就是在不断地遇到问题解决问题.之前学习asyncio模块学的一知半解,后来想起MultiProcessin ...
- Python_@修饰器(装饰器)的理解
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的作用就是为已经存在的对象添加额外的功能. def funA(fun): print (fun( ...
- json.parseArray源码解析
json.parseArray源码解析 public static <T> List<T> parseArray(String text, Class<T> cla ...
- gevent程序员指南
gevent程序员指南 由Gevent社区编写 gevent是一个基于libev的并发库.它为各种并发和网络相关的任务提供了整洁的API. 介绍 本指南假定读者有中级Python水平,但不要求有其 ...
- aliyun ubuntu读取第三方源被forbidden的问题
使用下面指令添加了一个源: sudo add-apt-repository ppa:webupd8team/java 然后update的时候提示: W: Failed to fetch http:// ...
- Wooden Sticks -HZNU寒假集训
Wooden Sticks There is a pile of n wooden sticks. The length and weight of each stick are known in a ...
- Qt中的ui指针和this指针
初学qt,对其ui指针和this指针产生疑问,画了个把小时终于搞懂了. 首先看ui指针的定义: 在mainwindow.h中 private: Ui::MainWindow *ui; Ui又是什么? ...
- Java并发-容器
同步容器类:同步容器类包括Vector和Hashtable.这些类实现线程安全的方式是:将它们的状态封装起来,并对每个公有方法进行同步,使得每次只有一个线程可以访问容器的状态.JDK1.2之后,提供了 ...
- 树莓派配置watchdog
安装watchdog apt install watchdog 编辑/etc/modules,添加bcm2708_wdog 编辑/etc/watchdog.conf watchdog-device = ...