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

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介:

之前的文章分析过,接受索引请求处理的代码在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]
}
复制代码

 














本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/6582369.html,如需转载请自行联系原作者


相关文章
|
机器学习/深度学习 数据采集 人工智能
人工智能安全(下)
人工智能安全(下)
1150 0
人工智能安全(下)
|
缓存 供应链 监控
“库存管理API:自动同步,避免超卖缺货”
库存管理API旨在实时同步库存数据,确保线上线下一致性,减少人工误差。其核心功能包括自动化更新、多平台接入及事件驱动的同步机制,有效避免超卖与缺货问题。通过Webhook回调、批量处理和分布式事务管理,实现高效数据传输。API支持预占库存、阈值预警和多级缓存优化,应对高并发场景。典型接口如`/api/inventory/sync`提供库存增减操作,并包含错误处理机制。集成时需关注测试验证、幂等性设计及性能监控,助力企业优化采购与仓储策略。
|
12月前
|
图形学 开发者
【Unity3D实例-功能-移动】角色移动-通过WSAD(CharacterController方式)
本文介绍了如何在Unity中使用CharacterController组件实现角色灵活移动。内容包括模型准备、动画处理、添加组件、编写移动脚本及测试运行,帮助开发者快速掌握角色控制技巧,打造流畅的游戏体验。
548 0
|
PyTorch 算法框架/工具 Swift
ms swift torch 与 transformer版本问题造成的nonetype error
当使用ms swift时,需确保安装PyTorch≥2.5.0版本,否则transformer的并行策略将被设为None,导致在并行检测中出现“Nonetype not iterable”错误。
439 0
|
编解码 监控 算法
CDN+OSS边缘加速实践:动态压缩+智能路由降低30%视频流量成本(含带宽峰值监控与告警配置)
本方案通过动态压缩、智能路由及CDN与OSS集成优化,实现视频业务带宽成本下降31%,首帧时间缩短50%,错误率降低53%。结合实测数据分析与架构创新,有效解决冷启动延迟、跨区域传输及设备适配性问题,具备快速投入回收能力。
874 0
基本时间单位 | 带你读《5G 空口设计与实践进阶 》之十五
为提供精确、一致的时间度量,NR 定义了最小时间单位 Tc。
基本时间单位 | 带你读《5G 空口设计与实践进阶 》之十五
|
监控 NoSQL 物联网
AliOS Things 维测高阶能力之数据断点(DWT)使用
### 1.    数据断点DWT介绍 在ARM Cortex-M及A系列CPU中,有很多调试组件,使用它们可以执行各种调试功能,包括断点(breakpoint)、数据段点(Data WatchPoint 即 DWT)及各种跟踪(trace)等。 硬件调试模块允许内核在访问数据断点时停止。内核停止时,内核的内部状态和系统的外部状态都是可以查询的。完成查询后,内核和外设可以被复原,程序将
2289 0
notepad快捷键大全
Notepad++ 快捷键 大全Ctrl+C 复制Ctrl+X 剪切Ctrl+V 粘贴Ctrl+Z 撤消Ctrl+Y 恢复Ctrl+A 全选Ctrl+F 键查找对话框启动Ctrl+H 查找/替换对话框Ctrl+D 复制并粘贴当行Ctrl+L 删除当前行Ctrl+T 当行向上移动一行F3 查找下一个S...
3819 0
|
数据可视化 算法 数据挖掘
8 个精彩的免费 G​​IS 软件资源分享
8 个精彩的免费 G​​IS 软件资源分享
653 0
8 个精彩的免费 G​​IS 软件资源分享
|
JavaScript 前端开发 算法
Solid,一个前端超新星项目?
本文适合对新兴前端技术框架感兴趣的小伙伴阅读
Solid,一个前端超新星项目?