Lucene.Net 2.3.1开发介绍 —— 三、索引(五)

原文:Lucene.Net 2.3.1开发介绍 —— 三、索引(五)

话接上篇,继续来说权重对排序的影响。从上面的4个测试,只能说是有个直观的理解了。“哦,是!调整权重是能影响排序了,但是好像没办法来分析到底怎么调啊!”。似乎是这样,现在需要把问题放大,加大索引的内容。到博客园新闻区,用zzk找了4篇内容包含“测试”的文章。代码变成 2.1.5

代码2.1.5
  1using System;
  2using System.Collections.Generic;
  3using Lucene.Net.Analysis;
  4using Lucene.Net.Analysis.Standard;
  5using Lucene.Net.Documents;
  6using Lucene.Net.Index;
  7using Lucene.Net.QueryParsers;
  8using Lucene.Net.Search;
  9using NUnit.Framework;
 10
 11namespace Test
 12{
 13    [TestFixture]
 14    public class StandardAnalyzerCaseTest
 15    {
 16        /**//// <summary>
 17        /// 执行测试的入口
 18        /// </summary>
 19        [Test]
 20        public void SearcherTest()
 21        {
 22            Index();
 23            List<string> list = new List<string>() { "测试" };
 24            for (int i = 0; i < list.Count; i++)
 25            {
 26                Console.WriteLine("搜索词:" + list[i]);
 27                Console.WriteLine("结果:");
 28                Searcher(list[i]);
 29                Console.WriteLine("-----------------------------------");
 30            }
 31        }
 32
 33        /**//// <summary>
 34        /// 搜索
 35        /// </summary>
 36        /// <param name="querystring">搜索输入</param>
 37        private void Searcher(string querystring)
 38        {
 39            Analyzer analyzer = new StandardAnalyzer();
 40            IndexSearcher searcher = new IndexSearcher("IndexDirectory");
 41            QueryParser parser = new QueryParser("content", analyzer);
 42            Query query = parser.Parse(querystring);
 43            Hits hits = searcher.Search(query);
 44            for (int i = 0; i < hits.Length(); i++)
 45            {
 46                Document doc = hits.Doc(i);
 47
 48                Console.WriteLine(doc.Get("title") + "_得分:" + hits.Score(i).ToString("f2"));
 49            }
 50        }
 51
 52/**//// <summary>
 53/// 索引数据
 54/// </summary>
 55private void Index()
 56{
 57    Analyzer analyzer = new StandardAnalyzer();
 58    IndexWriter writer = new IndexWriter("IndexDirectory", analyzer, true);
 59    AddDocument(writer, "微软Office 14即将展开Alpha测试", @"据国外网站消息,软件巨头微软可能即将展开Office 14的Alpha测试,据消息来源声称,微软下一版Office的Alpha测试日期可能在11月或12月。
 60
 61  微软商业智能团队的Hayley Rixon表示,根据技术检测程序(TAP),他们即将展开OPPS功能进行检测和分析。
 62
 63  其中OPPS(Office性能优化服务)是Office 14中的一个组成部分,可对商业业绩进行分析。据称OPPS Alpha项目将在8月28日发布,而其他Office 14功能的详情微软则没有透露。
 64
 65  这些内容最早公布于Rixon的博客,不过随后该页面即被移除。 ", 1.0f);
 66    AddDocument(writer, "IBM和微软将测试云计算的新的极限", @"[计世网消息](胡杨 编译) IBM iDataPlex服务器阵列将作为微软Windows高性能集群操作系统的测试硬件。IBM和微软将联合测试高性能计算和云计算领域的新的极限。
 67
 68  IBM在6月27日宣布,微软将是其iDataPlex服务器阵列的第一个客户。IBM是在今年4月首次推出这个x86服务器系统的,主要是用于建立运计算、Web 2.0应用程序和高性能计算的企业基础设施。
 69
 70  在这次合作中,微软Windows服务器部门计划使用一个全部安装iDataPlex系统的数据中心测试和评定微软Windows HPC Server 2008高性计算机能集群操作系统。多年以来,高性能计算和超级计算领域一直由Linux占统治地位。微软期待着改变这种情况。微软最近宣布,它将帮助建造一个性能达到每秒68.5万亿次计算的超级计算机。
 71
 72  虽然微软和IBM在某些领域的竞争非常激烈,但是,这两家公司还需要相互合作。这个合作协议对于这两家公司都有帮助。
 73
 74  对于微软来说,这个合作交易将帮助微软进入进入高性能计算和超级计算机领域。IBM的iDataPlex能够让微软利用这个技术测试自己的操作系统。微软计划在公司总部附近的设施中安装IBM iDataPlex系统。
 75
 76  为了帮助进行高性能计算,IBM还使用英特尔Xeon四核5400处理器(时钟速度为3.0GHz)扩展了iDataPlex的性能,把IBM的一个新的135平方英尺的模块数据中心的性能提高到了每秒145万亿次计算。
 77
 78  对于IBM来说,这笔交易将使iDataPlex的应用有一个良好的起步,从而为IBM赢得更多的大客户。IBM计划大举进入云计算领域,获得微软、谷歌和雅虎等大客户。 ", 1.0f);
 79    AddDocument(writer, "谷歌测试人力翻译服务 有利于推广其支付平台", @"据国外媒体报道,Google(谷歌)Blogscoped博客业务部门主管菲利浦·伦森 (Philipp Lenssen)近日证实,该公司已推出了一项人力翻译服务。虽然目前该服务仍处于测试阶段,但分析人士认为,Google正式推出这项服务后,将有利于提高Google Checkout支付平台的用户数量。
 80
 81伦森称,Google这项人力翻译服务名称为“Google翻译中心”,目前仅对特定测试者开放,但预计不久后将扩大测试范围。Google人力翻译服务的大致操作流程是:翻译客户首先把需要翻译的材料提交到Google翻译中心,该中心把相应材料交给专业翻译人员;翻译人员完成工作后,再由Google翻译中心转交给翻译客户。
 82
 83据悉,Google翻译中心可承接全球40种主要语言材料的翻译任务。目前还不能肯定 Google是否会担任客户和译者之间支付中间人,但如果Google这样做,该公司肯定会向翻译客户推荐其Google Checkout支付平台。除此之外,Google还可为客户和译者提供在线存储和管理工具,以方便他们对翻译材料进行有序管理。
 84
 85分析人士还认为,鉴于Google此前推出了在线百科全书服务Knol,或许Google将聘请专业翻译人员把相应词条翻译成其他语言,从而使Knol用户量成倍增长。而这种方式也符合Google“多多益善”的内容发展战略。(编译/中涛) 
 86", 1.0f);
 87    AddDocument(writer, "最聪明的浏览器和操作系统", @"IQ联盟维护着一个在线“60秒智商测试”。非常有意思的是,他们把测试结果和服务器上的日志进行了一番统计。将城市和国家之类地理位置,测试者使用的操作系统/浏览器等结合起来,得出了 最聪明的浏览器和操作系统。结论是:最聪明的人使用的是未知平台的Firefox(推测该平台可能是MacOS-Intel),最笨的人使用的是IE on WinNT。他们还评出了世界最聪明的网站:第一是ScienceBlogs.com,第二是Slashdot.org。以及最聪明的国家:第一是摩尔多瓦,第二是泰国,中国的IQ为83.77,排在66位。(这些结果会实时变动,现在最聪明的人使用的浏览器是Netscape on WinXP,最聪明的网站是test.qml.net)。
 88", 1.0f);
 89    writer.Optimize();
 90    writer.Close();
 91}
 92        /**//// <summary>
 93        /// 为索引准备数据
 94        /// </summary>
 95        /// <param name="writer">索引实例</param>
 96        /// <param name="content">需要索引的数据</param>
 97        void AddDocument(IndexWriter writer, string title, string content, float boost)
 98        {
 99            Document document = new Document();
100            document.Add(new Field("title", title, Field.Store.YES, Field.Index.TOKENIZED));
101            document.Add(new Field("content", content, Field.Store.YES, Field.Index.TOKENIZED));
102            document.SetBoost(boost);
103            writer.AddDocument(document);
104        }
105    }
106}

OK,测试一下。

搜索词:测试
结果:
最聪明的浏览器和操作系统_得分:0.17                                         //第四条记录,字数最少
微软Office 14即将展开Alpha测试_得分:0.14                                //第一条记录,字数和第三条相差不大
谷歌测试人力翻译服务 有利于推广其支付平台_得分:0.13                 //第三条记录,和第一条记录字数差不太多
IBM和微软将测试云计算的新的极限_得分:0.12                              //第二条记录,字数最多
-----------------------------------

可以看出,文档长度,测试都有一定的影响。现在试着把分少的往高调。把第二条记录增加0.1的权重。

搜索词:测试
结果:
最聪明的浏览器和操作系统_得分:0.17
IBM和微软将测试云计算的新的极限_得分:0.15
微软Office 14即将展开Alpha测试_得分:0.14
谷歌测试人力翻译服务 有利于推广其支付平台_得分:0.13
-----------------------------------

晕倒,怎么上面两条也变掉了?那是因为Lucene.Net中权重最小的文档是计算其他文档的一个基础。其它文档的分是以这个为基础,算出来的。因此改变最小的会影响好多个。不过这个影响现在并没有影响排序。而再加0.1,就变成了:

搜索词:测试
结果:
最聪明的浏览器和操作系统_得分:0.17
IBM和微软将测试云计算的新的极限_得分:0.15
微软Office 14即将展开Alpha测试_得分:0.14
谷歌测试人力翻译服务 有利于推广其支付平台_得分:0.13
-----------------------------------

跑到第二位去了。可见每增加0.1,会对结果造成很大的变动。而且干扰似乎也不是太大,看来0.1就够了。现在试试把权重还原,然后调整第一条记录的权重。增加0.1后变成:

搜索词:测试
结果:
微软Office 14即将展开Alpha测试_得分:0.17
最聪明的浏览器和操作系统_得分:0.17
谷歌测试人力翻译服务 有利于推广其支付平台_得分:0.13
IBM和微软将测试云计算的新的极限_得分:0.12
-----------------------------------

下面的基础值又回去了,而第一条也跑到第一位去了。

现在假设我要把第二条记录调到第一位,其他地方权重全部还原。把第一第三条记录对调一下。嘿嘿,我设置个30,肯定能到第一位了吧!测试结果:

搜索词:测试
结果:
IBM和微软将测试云计算的新的极限_得分:1.00
最聪明的浏览器和操作系统_得分:0.04
微软Office 14即将展开Alpha测试_得分:0.04
谷歌测试人力翻译服务 有利于推广其支付平台_得分:0.03
-----------------------------------

是到第一位去了,不过其他文档的得分都快变成0了。原来,在Lucene.Net中,文档的最高评分就是1。如果一旦有文档到了1,那么其他文档都会根据这个1的含金量进行调整。比如你把它的权重调成10000,那么其他的都会变成0,但这并不会影响排序。你要有耐心,一点点调试,就会看到,在文档分接近1的过程中,其他文档的分不会发生改变,而一旦到了1还有加,其他的文档分都会变低。永远不会有两个文档评分都到1。

现在再来试试完全匹配。把第四条记录的内容就换成测试两个字。那么它的评分会高达0.97分。其他值一般需要权重调正到8,才能和它抗衡。调整0.1就会对索引结果产生很大影响,如果设置权重,一般是按一套规则来做的,如果,大家都设置很大的数字,得分就会都很高,对于有时候需要给你的广告客户设置个第一位置来说,就容易产生混乱。混乱的问题呆会再说,现在要说的是字数少的评分太高的问题。有两个办法解决,一个就是降低字数过少内容的权重,但是注意不要设置为0,设置为0就认为是没有包含查询关键字了;另一个办法就是修改评分。修改评分等说到搜索的时候再来讲。

现在再来看看刚才说到的混乱问题,这个问题很重要。如果你要设置一个文档在搜索一个关键字的时候在第一位,你设置了它很高的权重,那么问题也来了,对于其他词,其它它包含的词,它也会跑到前面去。看来把文档的权重设置太高也不好,个人认为以0.1为单位就足够了,当然对于一些应用需要自己把握。比如,对于论坛帖子,一个回复你给它加0.1分也不是个好主意。

以上的讨论都是基于感性的认识,真正要研究,还需要对公式的增长曲线进行严格的分析才能下定论!

那要置顶要怎么办呢?这就要从另外一种设置权重的方法讲起了。

时间: 2024-11-25 14:25:50

Lucene.Net 2.3.1开发介绍 —— 三、索引(五)的相关文章

Lucene.Net 2.3.1开发介绍 —— 三、索引(四)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(四) 4.索引对搜索排序的影响 搜索的时候,同一个搜索关键字和同一份索引,决定了一个结果,不但决定了结果的集合,也确定了结果的顺序.那个这个结果是怎么得出来的?这个顺序又是怎么排的呢?这两个问题不是本节讨论的重点,但是这两个问题却关系到本节要讨论的,索引对结果的影响问题.在不使用字段排序的情况下,Lucene.Net默认是按文档的得分来排序的,这个公式看着很复杂,感觉像是大学时高数书上的那些个公式,其实说清楚了也简单. 关于文档排序

Lucene.Net 2.3.1开发介绍 —— 三、索引(七)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(七) 5.IndexWriter 索引这部分最后讲的是IndexWriter.如果说前面提到的都是数据的结构,那么IndexWriter就是业务的封装.无论述Document,Field还是看不见的Segment,Term都是对数据存储逻辑的抽象,IndexWriter包装了操作的过程. 当然,这里不会讨论IndexWriter的每个细节,这里主要介绍IndexWriter的常用法和实际使用中遇到的部署问题. 5.1 IndexWr

Lucene.Net 2.3.1开发介绍 —— 三、索引(六)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(六) 2.2 Field的Boost 如果说Document的Boost是一条线,那么Field的Boost则是一个点.怎么理解这个点呢?设置Document的Boost会影响所有字段.在搜索的过程中,一般至少会搜索两个Field,比如同时搜索标题和内容.而Document的Boost将同时影响标题和内容的搜索得分,但是设置Field的Boost则不会有那么大的影响,Field的Boost只会影响一个点.那这个点有什么用呢? 现在来

Lucene.Net 2.3.1开发介绍 —— 三、索引(二)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(二) 2.索引中用到的核心类 在Lucene.Net索引开发中,用到的类不多,这些类是索引过程的核心类.其中Analyzer是索引建立的基础,Directory是索引建立中或者建立好存储的介质,Document和Field类是逻辑结构的核心,IndexWriter是操作的核心.其他类的使用都被隐藏掉了,这也是为什么Lucene.Net使用这么方便的原因. 2.1 Analyzer 前面已经对Analyzer进行了很详细的讲解,Ana

Lucene.Net 2.3.1开发介绍 —— 三、索引(三)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(三) 3.Field配置所产生的效果 索引数据,简单的代码,只要两个方法就搞定了,而在索引过程中用到的一些类里最简单,作用也不小的就是Field,接下来看看Field的各项设置都会有什么样的效果. 代码 3.1 Code 1/**//// <summary> 2/// 索引数据 3/// </summary> 4private void Index() 5{ 6    Analyzer analyzer = new S

Lucene.Net 2.3.1开发介绍 —— 三、索引(一)

原文:Lucene.Net 2.3.1开发介绍 -- 三.索引(一) 在说索引之前,先说说索引是什么?为什么要索引?怎么索引? 先想想看,假如现在有一个文本,我们会怎么去搜索.比如,有一个string = "abcdefghijklmnopqrstuvwxyz",这都是26个字母.现在要看看里面是不是有a,用IndexOf就可以很方便实现.现在数据量大了,在数据库里已经有100多条数据了,当然,利用数据库提供的操作方法,也可以很方便的查找.而这里先抛开数据库,把这100多条记录放到N个

Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)

原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(三) Lucene有表达式就有运算符,而运算符使用起来确实很方便,但另外一个问题来了. 代码 4.3.4.1 Analyzer analyzer = new StandardAnalyzer(); QueryParser parser = new QueryParser("title", analyzer); Query query = parser.Parse(@":"); Console.Write

Lucene.Net 2.3.1开发介绍 —— 二、分词(三)

原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(三) 1.3 分词器结构 1.3.1 分词器整体结构 从1.2节的分析,终于做到了管中窥豹,现在在Lucene.Net项目中添加一个类关系图,把TokenStream和他的儿孙们统统拉上去,就能比较好的把握他们之间的关系. 图 1.3.1.1 如图1.3.1.1 就是他们的类关系图.看出如果要做一个分词器,最短的路,就是继承第二代,成为第三代.然后再写一个Analyzer的子类,专门用来做新分词器的适配器就好了.转换器.  呵呵,写

Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)

原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(一) 既然是内容筛选,或者说是搜索引擎,有索引,必然要有搜索.搜索虽然与索引有关,那也只是与索引后的文件有关,和索引的程序是无关的,因此,搜索和索引一般是分开部署.简单地说,就是一个应用程序(桌面程序)来索引,一个WEB程序来实现搜索.当然,为了测试的时候简单,这里还是使用NUnit的方式运行.搜索讲完后,将会简单介绍单机搜索引擎如何部署. 4.1 搜索与什么有关 搜索与什么有关呢?即使没有看过前面的文章,那么现在来随便猜一猜. 首