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的更多相关文章

  1. wukong引擎源码分析之索引——part 1 倒排列表本质是有序数组存储

    searcher.IndexDocument(0, types.DocumentIndexData{Content: "此次百度收购将成中国互联网最大并购"}) engine.go ...

  2. wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用

    之前的文章分析过,接受索引请求处理的代码在segmenter_worker.go里: func (engine *Engine) segmenterWorker() { for { request : ...

随机推荐

  1. LeetCode(43)-Contains Duplicate II

    题目: Given an array of integers and an integer k, find out whether there are two distinct indices i a ...

  2. machine learning 之 Neural Network 2

    整理自Andrew Ng的machine learning 课程 week5. 目录: Neural network and classification Cost function Backprop ...

  3. Jquery的过滤选择器分为哪几种?

    Jquery的过滤选择器分为哪几种? 转载▼ 标签: jquery 过滤选择器 分类 分类: JQuery 所有的过滤选择器分为哪几种: 一.基本过滤选择器(重点掌握下列八个) :first 选取第一 ...

  4. python3 数据科学基础

    第一章 1.Anaconda(最著名的python数据科学平台) 下面小伙伴们咱们来初初识下Anaconda吧 What is Anaconda???? 回答: (1).科学计算的平台 (2).有很多 ...

  5. svn Server sent unexpected return value (403 Forbidden) in response to CHECKOUT

    今天,提交資料到公司svn服務器,但是一直提示 Server sent unexpected return value (403 Forbidden) in response to CHECKOUT ...

  6. jsoup 使用总结4--高级用法之 script js 脚本

    jsoup 使用总结4--高级用法之 script js 脚本 大部分时候,我们使用jsoup解析网页的时候,都是直接找到某一类元素,或者按某种selector查询:具体使用方法可以参考jsoup官网 ...

  7. Pycharm安装教程

    1.下载PyQt 官方网站:http://www.riverbankcomputing.com/software/pyqt/download5 我的操作系统是64位的,安装的是Python3.4.3, ...

  8. php中的session_id详解

    php中session_id()函数原型及说明session_id()函数说明:stringsession_id([string$id])session_id() 可以用来获取/设置 当前会话 ID. ...

  9. PyQuery详解

    1.What is Pyquery? 答:灵活强大的网页解析库 2.安装: pip3 install pyquery 3.基本使用 初始化操作: 前言:在介绍之前小伙伴们我们先来了解下CSS的基本语法 ...

  10. 数据准备<3>:数据预处理

    数据预处理是指因为算法或者分析需要,对经过数据质量检查后的数据进行转换.衍生.规约等操作的过程.整个数据预处理工作主要包括五个方面内容:简单函数变换.标准化.衍生虚拟变量.离散化.降维.本文将作展开介 ...