Lucene.net查询不准确可能是什么原因

问题描述

我用盘古分词+Lucene.net做了一个全文检索的功能,但是有一个bug,比如输入“质量-安全”,结果应该是只含“质量”关键字不含“安全”关键字,但是实际查询出来的,有个别结果(大部分结果符合要求)既有“质量”关键字,也有“安全”关键字。有哪位熟悉Lucene.net的老师指导一下,出现这个bug可能的原因是什么?可能是建索引那里的问题吗?还是分词有问题?

解决方案

解决方案二:
上代码创建索引privatestaticAnalyzer_analyzer;privatestaticAnalyzerAnalyzer{get{if(_analyzer==null){_analyzer=newPanGuAnalyzer();}return_analyzer;}}privatevoidButton_Click(objectsender,RoutedEventArgse){varindexFolder=System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory,AppSettings.ChapterIndexDir);if(!System.IO.Directory.Exists(indexFolder)){System.IO.Directory.CreateDirectory(indexFolder);}vardirectory=FSDirectory.Open(newSystem.IO.DirectoryInfo(indexFolder));//创建索引(索引存放目录,盘古解析器,索引创建方式【true:重新新建索引;false:从旧的索引执行追加】,文件长度是否限制)varwriter=newIndexWriter(directory,Analyzer,true,IndexWriter.MaxFieldLength.UNLIMITED);ISessionsession=NhbServiceHelper.OpenSession();stringqueryString=@"selects.id,s.name,s.contenfromd_std_documents";NHibernate.IQueryquery=session.CreateSQLQuery(queryString);IEnumerablelist=query.List();try{foreach(object[]iteminlist){CustomFieldCustom=newCustomField(){ID=item[0].ToString(),Name=ConvertStringIsNull(item[1]),Content=ConvertStringIsNull(item[2])};DoSingleIndexCreation(writer,Custom);}writer.Optimize();writer.Dispose();MessageBox.Show("创建索引成功!");}catch(Exceptionex){MessageBox.Show("创建索引失败:"+ex.Message);}}///<summary>///创建索引Document和往文档写入索引内容///Document是索引文档,可理解为数据库里的记录///Filed是索引文档中的字段,可理解为数据库里的字段(字段名称,是否存储,是否索引)///</summary>///<paramname="writer"></param>///<paramname="record"></param>privatevoidDoSingleIndexCreation(IndexWriterwriter,CustomFieldrecord){vardoc=newDocument();//不分词索引doc.Add(newField("编号",record.ID,Field.Store.YES,Field.Index.NOT_ANALYZED));//既创建分词索引、又创建不分词索引doc.Add(newField("文档名称",record.Name,Field.Store.YES,Field.Index.ANALYZED));doc.Add(newField("文档名称",record.Name,Field.Store.YES,Field.Index.NOT_ANALYZED));if(!string.IsNullOrEmpty(record.Content)){doc.Add(newField("文档内容",record.Content,Field.Store.YES,Field.Index.ANALYZED));doc.Add(newField("文档内容",record.Content,Field.Store.YES,Field.Index.NOT_ANALYZED));}writer.AddDocument(doc);}

查询///<summary>///当前使用的查询索引///</summary>///<paramname="key"></param>///<returns></returns>publicstaticDictionary<string,StandardInfoModel>GetResultData(stringkey,refList<string>keyToken){Dictionary<string,StandardInfoModel>lstResultData=newDictionary<string,StandardInfoModel>();if(string.IsNullOrWhiteSpace(AppSettings.ChapterIndexDir))returnnewDictionary<string,StandardInfoModel>();DirectorydirChapter=FSDirectory.Open(AppSettings.ChapterIndexDir);IndexSearchersearcher=newIndexSearcher(dirChapter,true);BooleanQuerybooleanQuery=newBooleanQuery();vartermList=GetSplitTerm(key);string[]fields={"文档名称","文档内容"};foreach(varitemintermList){//Occur的取值及含义MUST与SHOULD或MUST_NOT非keyToken.Add(item.Key);MultiFieldQueryParserparser=newMultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30,fields,analyzer);Queryquery=parser.Parse(item.Key);booleanQuery.Add(query,(Occur)item.Value);}}//TopScoreDocCollector盛放查询结果的容器TopScoreDocCollectorcollector=TopScoreDocCollector.Create(100000,true);//根据booleanQuery进行查询,查询结果放入collector容器searcher.Search(booleanQuery,collector);//TopDocs指定0到collector.TotalHits即所有查询结果中的文档ScoreDoc[]scoreDocArr=collector.TopDocs(0,collector.TotalHits).ScoreDocs;for(inti=0;i<scoreDocArr.Length;i++){Documentdocument=searcher.Doc(scoreDocArr[i].Doc);stringID=document.Get("编号");if(!lstResultData.ContainsKey(ID)){StandardInfoModeldocStandard=newStandardInfoModel();docStandard.ID=ID;docStandard.Name=document.Get("文档名称");stringcontent=document.Get("文档内容");lstResultData.Add(ID,docStandard);}else{lstResultData[ID].LstChapter.Add(document.Get("文档内容"));}}returnlstResultData;}///<summary>///获取每个关键字的最小分词成员Term///</summary>///<paramname="searchText"></param>///<returns></returns>publicstaticDictionary<string,object>GetSplitTerm(stringsearchText){Dictionary<string,object>lstResult=newDictionary<string,object>();Dictionary<string,object>lstSearchKey=GetSplitSearchKey(searchText);boolisFirst=true;foreach(variteminlstSearchKey){if(isFirst){lstResult.Add(item.Key,item.Value);isFirst=false;}TokenStreamtokenStream=analyzer.TokenStream(item.Key,newSystem.IO.StringReader(item.Key));//PanGu.Setting.PanGuSettings.Config.MatchOptions.SynonymOutput=true;boolhasNext=tokenStream.IncrementToken();//用于得到下一个TokenLucene.Net.Analysis.Tokenattributes.ITermAttributeita;while(hasNext){ita=tokenStream.GetAttribute<Lucene.Net.Analysis.Tokenattributes.ITermAttribute>();if(!lstResult.Keys.Contains(ita.Term)){lstResult.Add(ita.Term,item.Value);}hasNext=tokenStream.IncrementToken();}tokenStream.CloneAttributes();}analyzer.Close();returnlstResult.Distinct().ToDictionary(l=>l.Key,l=>l.Value);}///<summary>///如果关键字中存在逻辑符号,先拆分///</summary>///<paramname="searchText"></param>///<returns></returns>publicstaticDictionary<string,object>GetSplitSearchKey(stringsearchText){Dictionary<string,object>listResult=newDictionary<string,object>();Occuroccur=Occur.SHOULD;if(searchText.Contains("+")||searchText.Contains("-")){string[]strArr=searchText.Split(newchar[]{'+','-'},StringSplitOptions.None);for(inti=0;i<strArr.Length;i++){if(!string.IsNullOrEmpty(strArr[i])&&!listResult.Keys.Contains(strArr[i])){if(i==0){occur=searchText.Substring(0,1).Contains("-")?Occur.MUST_NOT:Occur.SHOULD;listResult.Add(strArr[0],occur);}else{intstartIndex=searchText.IndexOf(strArr[i-1])+strArr[i-1].Length;occur=searchText.Substring(startIndex,1).Contains("+")?Occur.MUST:Occur.MUST_NOT;listResult.Add(strArr[i],occur);}}}}else{listResult.Add(searchText,occur);}returnlistResult;}

解决方案三:
同问,我也遇到这个问题了,搜索“美丽”有结果,搜索“美”就没有结果了
解决方案四:
引用2楼liuruxi622的回复:

同问,我也遇到这个问题了,搜索“美丽”有结果,搜索“美”就没有结果了

是分词这方面的问题吧
解决方案五:
我的问题解决了,分词没问题,是Query的问题,也就是下面这段代码string[]fields={"文档名称","文档内容"};foreach(varitemintermList){//Occur的取值及含义MUST与SHOULD或MUST_NOT非keyToken.Add(item.Key);MultiFieldQueryParserparser=newMultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30,fields,analyzer);Queryquery=parser.Parse(item.Key);booleanQuery.Add(query,(Occur)item.Value);}}我觉得你的问题应该也是这个原因,Lucene.net有很多Query,有些是只能查词组不能查到单个的字,有些是可以加通配符查询比如查三国可以查到三国演义。建议你把Lucene.net的各种Query弄明白,然后根据自己的需求,去选择合适的Query。
解决方案六:
该回复于2015-08-15 00:03:31被版主删除

时间: 2024-08-30 01:14:28

Lucene.net查询不准确可能是什么原因的相关文章

在jsp页面中显示lucene的查询结果,报错:org.apache.jasper.JasperException: Java heap space

问题描述 在jsp页面中显示lucene的查询结果,当返回hits的总数小于100时,可以正常显示,当结果大于100,会报如下错误:(但是在java环境下结果输出是正常的)exceptionorg.apache.jasper.JasperException:Javaheapspaceorg.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:433)org.apache.jasper.

百度统计中索引量与site命令查询数差异较大的原因

自百度统计3.0推出之后,百度统计里面的功能百度索引量查询的功能成为了seo人 员的焦点,一是因为此项功能的数据更新时间做了调整,从原来的每周一次改为现在的每天一次;二是因为,好多站长反映百度索引量与site命令查询到的结果 有很大的差异.针对数据差异较大的问题,目前百度官方也没有给出确切解释,seo的知名人士也没有做相应解释.今天,孟则宇就来研究一下这个问题吧! 1.多数网站出现索引量数据与site查询结果数差异较大的情况 我在百度统计的官方贴吧,发现后很多人在反应这个问题,在贴吧首页里最少有

app-调用百度API做了个身份证信息查询APP,询问程序不能正常运行原因

问题描述 调用百度API做了个身份证信息查询APP,询问程序不能正常运行原因 package com.jingyou.id; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; im

用的lucene 为什么查询的结果重复呢

问题描述 用的lucene 索引建立没有重复 为什么查询的结果重复呢代码如下:IndexSearcher searchers = new IndexSearcher(LuceneManager.article_index_path);Analyzer analyzer = new LuceneManager().getAnalyzer();QueryParser queryParser = new QueryParser("title", analyzer);Query query =

lucene 范围查询及其原理

适用于lucene 6.0. Int类型的有IntPoint,Double类型的有相应的DoublePoint,以此类推. 1.相关类 org.apache.lucene.document.IntPoint 一个被索引的int类型的field.可以代表n维形状,可以范围搜索. org.apache.lucene.document.IntPoint.IntPoint(String name, int... point) 构造函数. Query org.apache.lucene.document.

WebGIS中兴趣点简单查询、基于Lucene分词查询的设计和实现

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 兴趣点查询是指:输入框中输入地名.人名等查询信息后,地图上可以展示出对应信息所在的地址,并且根据需求以不同方式展示出相关地址的属性信息等. 以百度地图为例:                         2.原理 所谓兴趣点查询,也就是前台输入描述信息后,后台根据该描述信息在地理数据库中查询到符合查询信息的地理数据和与此对应的属性数据,然后将数据返回给前台

Lucene分页只能查询是对搜索返回的结果进行分页,而不是对搜索结果的总数量进行分页,因此我们搜索的时候都是返回前n条记录?

问题描述 Lucene分页查询是对搜索返回的结果进行分页,而不是对搜索结果的总数量进行分页,因此我们搜索的时候都是返回前n条记录.?如果只能这样的话有没有什么方法性价比高点的方法? 解决方案

lucene 查询语法

Lucene所支持的查询语法可见http://lucene.apache.org/java/3_0_1/queryparsersyntax.html   新版6.0.0可见 : http://lucene.apache.org/core/6_0_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package_description (1) 语法关键字 + - && || ! ( ) { } [

在应用中加入全文检索功能——基于Java的全文索引引擎Lucene简介

全文检索|索引 内容摘要: Lucene是一个基于Java的全文索引工具包. 基于Java的全文索引引擎Lucene简介:关于作者和Lucene的历史 全文检索的实现:Luene全文索引和数据库索引的比较 中文切分词机制简介:基于词库和自动切分词算法的比较 具体的安装和使用简介:系统结构介绍和演示 Hacking Lucene:简化的查询分析器,删除的实现,定制的排序,应用接口的扩展 从Lucene我们还可以学到什么 基于Java的全文索引/检索引擎--Lucene Lucene不是一个完整的全