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 : ...
随机推荐
- ethtool确定网卡对应的物理网口
在配置有多个网络接口的设备时我们会犯难,eth0.eth1.--到底是那个接口? 我使用的机器是CentOS系统,打开终端,输入ethtool –help 显示帮助信息,下面我就简要介绍一下最常用的两 ...
- mongodb3.6 (五)net 客户端访问mongodb设置超时时间踩过的“坑”
前言 在上一篇文章中,我们有提到net访问mongodb连接超时默认为30秒,这个时间在实际项目中肯定是太长的.而MongoClientSettings 也确是提供了超时属性,如下图: 可实际使用中, ...
- DDD学习笔记1——分层架构
新旧架构对比图: DDD中的基础设施层包括数据持久化(ORM数据访问),IoC容器实现,AOP实现(安全,日志记录,缓存等) Repository的接口通常放在领域层,具体实现在基础设施层 旧架构的业 ...
- Centos7 时区的设置
Linux 系统(我特指发行版, 没说内核) 下大部分软件的风格就是不会仔细去考虑向后 的兼容性, 比如你上个版本能用这种程序配置, 没准到了下一个版本, 该程序已经不见了. 比如 sysvinit ...
- Java中常用的数据结构类
结构体系图 List ArrayList.LinkedList.Vector有什么区别? ArrayList 只能装入引用对象(基本类型要转换为封装类): 线程不安全: 底层由数组实现(顺序表),因为 ...
- Android集成ffmpeg
1.ffmpeg官网文档地址:https://trac.ffmpeg.org/wiki/CompilationGuide/Android 2.上面页面资源列表里面第一项 https://github. ...
- 2013-8:SDCE大会笔记
百度移动云三大开发框架:Clouda,SiteApp,AppBuilder MBaaS解决高性能Server很难的问题 百度开放云的区域运营服务于创业者 Pinterest架构变迁: 互联网就是把线下 ...
- 深入理解javascript 匿名函数和闭包
代码如下: (function(){ //这里忽略jQuery所有实现 })(); (function(){ //这里忽略jQuery所有实现 })(); 半年前初次接触jQuery的时候,我也像其 ...
- 设计模式之模板方法(Template Method)
在整理模板方法之前,先来说点废话吧.除了记录学习总结,也来记录一下生活吧. 我们公司的老板在北京,老板也会因为项目来公司,不过不是天天来.公司有个同事,只要老板不在就天天迟到,而且一天比一天晚,经常来 ...
- AXIS2整合spring需要的jar,以及大部分缺少jar所报的异常
axis2 webservice 服务端jar包: -->axis2-kernel-1.6.1.jar -->axis2-spri ...