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. cocos2dx 跨平台编译遇到的几个问题

    首先声明一下自己用的版本 vs2010   cocos2d-x_2.2    ndk_r9 1. 安装cygwin之后,也设置好了 ndk_root, 但是 cd $NDK_ROOT 进入不了, 只好 ...

  2. Spring Aop中,获取被代理类的工具

    在实际应用中,顺着过去就是一个类被代理.反过来,可能需要逆向进行,拿到被代理的类,实际工作中碰到了,就拿出来分享下. /** * 获取被代理类的Object * @author Monkey */ p ...

  3. The 4 Essentials of Video Content Marketing Success

    https://www.entrepreneur.com/article/243208 As videos become increasingly popular, they provide the ...

  4. Angular5 宏观把控

    1.首先,Angular5相对于Angular4有了一些新的特性: (1)i18n国际化管道: (2)一个组件可以以多个名称导出: (3)使用httpClient: 相比于http,httpClien ...

  5. 给你的网页添加一个随机的BGM

    大晚上的,突然想到,我这么喜欢听歌的人,博客里怎么能少了BGM呢,说干就干. 首先,给博客侧边栏加一个空div:<div id="music"></div> ...

  6. Django模型层之字段查询参数及聚合函数

    该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. 字段查询是指如何指定SQL WHERE子句的 ...

  7. 一天搞懂深度学习-训练深度神经网络(DNN)的要点

    前言 这是<一天搞懂深度学习>的第二部分 一.选择合适的损失函数 典型的损失函数有平方误差损失函数和交叉熵损失函数. 交叉熵损失函数: 选择不同的损失函数会有不同的训练效果 二.mini- ...

  8. 深入理解SpringAOP之代理对象

    本篇文章主要带大家简单分析一下AOP的代理对象,至于AOP是什么,如何配置等基础性知识,不在这里讨论.阅读前请先参考:代理模式,在这之前我们需要了解springframework的三个核心接口与get ...

  9. 30岁天才上班族利用Python人脸监控BOSS,伪装成认真上班的样子!

    如今Python程序员可以做深度学习算法实现人脸识别,得益于国外开源框架,虽然它不能达到face++和众多人脸识别公司,但实际应用并没有受到太大的压力.下图为tensorflow的5点定位加情感测试. ...

  10. CentOS-Minimal版本下安装telnet服务和xinetd服务

    默认在CentOS-Minimal版本下没有安装telnet和xinetd服务. 1.安装telnet [root@localhost ~]# rpm -qa | grep telnet  --检查是 ...