package core

import (
    "github.com/huichen/wukong/types"
    "github.com/huichen/wukong/utils"
    "log"
    "sort"
    "sync"
)

type Ranker struct {
    lock struct {
        sync.RWMutex
        fields map[uint64]interface{}
        docs   map[uint64]bool
    }
    initialized bool
}

func (ranker *Ranker) Init() {
    if ranker.initialized == true {
        log.Fatal("排序器不能初始化两次")
    }
    ranker.initialized = true

    ranker.lock.fields = make(map[uint64]interface{})
    ranker.lock.docs = make(map[uint64]bool)
}

// 给某个文档添加评分字段
func (ranker *Ranker) AddDoc(docId uint64, fields interface{}) {
    if ranker.initialized == false {
        log.Fatal("排序器尚未初始化")
    }

    ranker.lock.Lock()
    ranker.lock.fields[docId] = fields
    ranker.lock.docs[docId] = true
    ranker.lock.Unlock()
}

// 删除某个文档的评分字段
func (ranker *Ranker) RemoveDoc(docId uint64) {
    if ranker.initialized == false {
        log.Fatal("排序器尚未初始化")
    }

    ranker.lock.Lock()
    delete(ranker.lock.fields, docId)
    delete(ranker.lock.docs, docId)
    ranker.lock.Unlock()
}

// 给文档评分并排序
func (ranker *Ranker) Rank(
    docs []types.IndexedDocument, options types.RankOptions, countDocsOnly bool) (types.ScoredDocuments, int) {
    if ranker.initialized == false {
        log.Fatal("排序器尚未初始化")
    }

    // 对每个文档评分
    var outputDocs types.ScoredDocuments
    numDocs := 0
    for _, d := range docs {
        ranker.lock.RLock()
        // 判断doc是否存在
        if _, ok := ranker.lock.docs[d.DocId]; ok {
            fs := ranker.lock.fields[d.DocId]
            ranker.lock.RUnlock()
            // 计算评分并剔除没有分值的文档
            scores := options.ScoringCriteria.Score(d, fs)
            if len(scores) > 0 {
                if !countDocsOnly {
                    outputDocs = append(outputDocs, types.ScoredDocument{
                        DocId:                 d.DocId,
                        Scores:                scores,
                        TokenSnippetLocations: d.TokenSnippetLocations,
                        TokenLocations:        d.TokenLocations})
                }
                numDocs++
            }
        } else {
            ranker.lock.RUnlock()
        }
    }

    // 排序
    if !countDocsOnly {
        if options.ReverseOrder {
            sort.Sort(sort.Reverse(outputDocs))
        } else {
            sort.Sort(outputDocs)
        }
        // 当用户要求只返回部分结果时返回部分结果
        var start, end int
        if options.MaxOutputs != 0 {
            start = utils.MinInt(options.OutputOffset, len(outputDocs))
            end = utils.MinInt(options.OutputOffset+options.MaxOutputs, len(outputDocs))
        } else {
            start = utils.MinInt(options.OutputOffset, len(outputDocs))
            end = len(outputDocs)
        }
        return outputDocs[start:end], numDocs
    }
    return outputDocs, numDocs
}

ranker.go的更多相关文章

  1. 理解AUC

    本文主要讨论了auc的实际意义,并给出了auc的常规计算方法及其证明 转载请注明出处:http://www.cnblogs.com/van19/p/5494908.html 1 ROC曲线和auc 从 ...

  2. RankLib参数翻译

    写在前面,metric2t指标详解: NDCG(Normalized discounted cumulative gain)即DCG/IDCGCG(cumulative gain)DCG(Discou ...

  3. 使用Weka进行数据挖掘

    1.简介 数据挖掘.机器学习这些字眼,在一些人看来,是门槛很高的东西.诚然,如果做算法实现甚至算法优化,确实需要很多背景知识.但事实是,绝大多数数据挖掘工程师,不需要去做算法层面的东西.他们的精力,集 ...

  4. Sphinx 2.2.6 window下安装全过程 未完 持续标记~~~~

    由于在win8.1下安装 选的这个版本 Win64 binaries w/MySQL+PgSQL+libstemmer+id64 support 2.2.6-release 7.3M 下载页面 htt ...

  5. Weka使用介绍

    (转) http://baidutech.blog.51cto.com/4114344/1033714/ 1.简介 数据挖掘.机器学习这些字眼,在一些人看来,是门槛很高的东西.诚然,如果做算法实现甚至 ...

  6. 【Machine Learning】wekaの特征选择简介

    看过这篇博客的都应该明白,特征选择代码实现应该包括3个部分: 搜索算法: 评估函数: 数据: 因此,代码的一般形式为: AttributeSelection attsel = new Attribut ...

  7. weka特征选择(IG、chi-square)

    一.说明 IG是information gain 的缩写,中文名称是信息增益,是选择特征的一个很有效的方法(特别是在使用svm分类时).这里不做详细介绍,有兴趣的可以googling一下. chi-s ...

  8. Codeigniter 集成sphinx搜索 这里采用的是coreseek中文搜索引擎,具体安装请参考官方网站

    先上效果图 加入sphinx类库(/application/libraries/sphinx_client.php) 0001 <?php 0002 0003 // 0004 // $Id: s ...

  9. php 连接测试sphinx

    shpinx.php <?php header("Content-type:text/html;charset=utf-8"); include 'SphinxClient. ...

随机推荐

  1. 面试之路(3)-详解MVC,MVP,MVVM

    一:mvc mvc结构: 视图(View):用户界面. 控制器(Controller):业务逻辑 模型(Model):数据保存 mvc各部分的通信方式 mvc互动模式 通过 View 接受指令,传递给 ...

  2. .net framework 4 线程安全概述

    线程安全:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的.早期的时候, ...

  3. dom4j 解析 xml标签属性

    重写onEnd()和onStart()方法 public class XmlElementHandler implements ElementHandler { @Override public vo ...

  4. 利用truffle与智能合约进行交互

    先了解相关指令,再观看比较合适:http://truffle.tryblockchain.org/ 安装: 先完成上一条博客的安装,再来进行下面的操作:http://www.cnblogs.com/t ...

  5. Webpack的配置与使用

    一.什么是Webpack?     WebPack可以看做是模块打包机.用于分析项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),将 ...

  6. jQuery匿名函数$(function(){ }

    搬运原地址:https://zhidao.baidu.com/question/473318430.html $(function(){ }实际上是匿名函数.这是JQuery的语法,$表示JQuery ...

  7. oracle 登录数据库时报 无监听 的一种解决方式(监听日志文件达到4g默认上限)

    问题:登录服务器时 报无监听服务 检查步骤: 1.进入sqlplus查看数据库的状态,显示当前数据库的状态为OPEN 脚本:select status from v$Instance; 2.检查数据库 ...

  8. -bash: ./switch.sh: /bin/bash^M: bad interpreter: No such file or directory

    问题: 偶然使用 windows 进行编写脚本.使用 wsl (windows subsystem for linux) 进行运行的时候,什么事情没有.但是当把脚本移植到远程服务器进行运行的时候,发现 ...

  9. Unix 和· Linux 系统概述

    一.Unix 1.Unix 定义 Unix 是一个计算机操作系统,一个用来协调.管理和控制计算机硬件和软件资源的控制程序 '2.Unix 特点 ① 多用户:在同一时刻可以有多个用户同时使用Unix操作 ...

  10. C#之Redis为所欲为

    一 Redis是一种支持多种数据结构的键值对数据库 1.1Redis下载地址 :https://github.com/MicrosoftArchive/Redis 建议下载 .msi结尾的应用程序进行 ...