使用Lucene.net进行全文查找多关键字匹配

简介:

Lucene是一个开源的搜索引擎,开发语言是Java,Lucene.net是它的.NET版本。可以在C#中方便的调用。

Lucene.net目前最新版本是3.0.3,你可以从官方网站下载到最新版本:http://lucenenet.apache.org/

使用Lucene.net进行全文查找首先要根据数据创建索引,然后再根据索引来查找关键字。本文不做任何原理性的解释,需要深入研究的请自行Google之。

创建索引

还是直接上代码的比较好:

复制代码
            IndexWriter writer = new IndexWriter(FSDirectory.Open(new DirectoryInfo(indexDirectory)),
                    analyzer, true, IndexWriter.MaxFieldLength.LIMITED);

            for (int i = 0; i < files.Count(); i++)
            {
                FileInfo fileInfo = files[i];
                StreamReader reader = new StreamReader(fileInfo.FullName);

                OutputMessage("正在索引文件[" + fileInfo.Name + "]");

                Document doc = new Document();
                doc.Add(new Field("FileName", fileInfo.Name, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field("Author", reader.ReadLine(), Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field("Content", reader.ReadToEnd(), Field.Store.NO, Field.Index.ANALYZED));
                doc.Add(new Field("Path", fileInfo.FullName, Field.Store.YES, Field.Index.NO));

                writer.AddDocument(doc);
                writer.Optimize();
            }

            writer.Dispose();
复制代码

在上面的代码中,我们对文本文件进行了索引,每一个文件都保存了FileName(文件名)、Author(作者)、Content(内容)、Path(文件路径)几个字段。跟数据库中的字段很相似。

 

使用中文分词

目前中文分词有Lucene.Net.Analysis.Cn.ChineseAnalyzer 和盘古分词,我们在测试中使用前者,更方便我们做测试。

Lucene.Net.Analysis.Cn.ChineseAnalyzer包含在源代码中,你可以把它复制到你的源代码中,也可以编译以后引用。我这里为了方便,直接复制到源代码中的。建议在实际使用的时候,编译然后添加引用。

 

全文查找

还是上代码吧,看上去更直接。

复制代码
            IndexReader reader = null;
            IndexSearcher searcher = null;
            try
            {
                reader = IndexReader.Open(FSDirectory.Open(new DirectoryInfo(indexDirectory)), true);
                searcher = new IndexSearcher(reader);
                //创建查询
                PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(analyzer);
                wrapper.AddAnalyzer("FileName", analyzer);
                wrapper.AddAnalyzer("Author", analyzer);
                wrapper.AddAnalyzer("Content", analyzer);
                string[] fields = {"FileName", "Author", "Content"};

                QueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, fields, wrapper);
                Query query = parser.Parse(keyword);
                TopScoreDocCollector collector = TopScoreDocCollector.Create(num, true);

                searcher.Search(query, collector);
                var hits = collector.TopDocs().ScoreDocs;

                int numTotalHits = collector.TotalHits;
                OutputMessage("查找 " + keyword + " ...共找到 " + numTotalHits + "个匹配的文档");

                //以后就可以对获取到的collector数据进行操作
                for (int i = 0; i < hits.Count(); i++)
                {
                    var hit = hits[i];
                    Document doc = searcher.Doc(hit.Doc);
                    Field fileNameField = doc.GetField("FileName");
                    Field authorField = doc.GetField("Author");
                    Field pathField = doc.GetField("Path");

                    OutputMessage(fileNameField.StringValue + "[" + authorField.StringValue + "],匹配指数:" + Math.Round(hit.Score * 100, 2) + "%");
                    OutputMessage(pathField.StringValue);
                    OutputMessage(string.Empty);
                }
            }
            finally
            {
                if (searcher != null)
                    searcher.Dispose();

                if (reader != null)
                    reader.Dispose();
            }
复制代码

上面的这段代码可以是实现多关键字的查找。需要说明的是,貌似在得到检索到的文档的地方,跟之前的版本有一些不同(我拷贝别人的代码没办法直接运行)……

另外,此处检索的行数受到num的影响,但返回的总行数是不受影响的,如果需要得到总行数,可以在第一次检索以后得到总行数,然后将总行数赋值给num,在进行新一次的检索。




本文转自齐师傅博客园博客,原文链接:http://www.cnblogs.com/youring2/archive/2012/12/14/2818311.html,如需转载请自行联系原作者

相关文章
|
索引
艾伟_转载:Lucene.net多字段多索引目录搜索
Lucene.net是目前在.net环境中被普遍使用的全文索引的开源项目,这次在项目的开发中也使用它进行全文索引。在开发过程中碰到一些小问题就是对多字段和多索引目录进行搜索。 1、多字段搜索就是同时要一个以上的字段中的内容进行比较搜索,类似概念在SQL中就是select * from Table where a like '%query%' or b like '%query%'。
879 0
|
自然语言处理 算法
一起谈.NET技术,HubbleDotNet 和 Lucene.Net 匹配相关度的比较
  很多网友在使用 Lucene.net (Lucene java 版本也是一样)后会感觉Lucene.net 的匹配相关度存在问题,搜索得到的结果往往不是希望的结果,不完全匹配的记录往往比完全匹配的记录排序还要靠前,很多人试图通过分词来解决,中文环境搜索,分词确实能解决一些问题,但不能根本解决问题,而英文环境下,分词根本无法解决任何问题。
1422 0
|
自然语言处理 索引 搜索推荐
Lucene.Net 2.3.1开发介绍 —— 四、搜索(一)
原文:Lucene.Net 2.3.1开发介绍 —— 四、搜索(一) 既然是内容筛选,或者说是搜索引擎,有索引,必然要有搜索。搜索虽然与索引有关,那也只是与索引后的文件有关,和索引的程序是无关的,因此,搜索和索引一般是分开部署。
1025 0
|
索引
Lucene.Net 2.3.1开发介绍 —— 四、搜索(二)
原文:Lucene.Net 2.3.1开发介绍 —— 四、搜索(二) 4.3 表达式用户搜索,只会输入一个或几个词,也可能是一句话。输入的语句是如何变成搜索条件的上一篇已经略有提及。 4.3.1 观察表达式在研究表达式之前,一定要知道,任何一个Query都会对于一个表达式。
1031 0
|
自然语言处理
Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)
原文:Lucene.Net 2.3.1开发介绍 —— 四、搜索(三) Lucene有表达式就有运算符,而运算符使用起来确实很方便,但另外一个问题来了。 代码 4.3.4.1Analyzer analyzer = new StandardAnalyzer();QueryParser parser ...
1061 0
|
自然语言处理
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
原文:Lucene.Net 2.3.1开发介绍 —— 二、分词(二) 1.2、分词的过程   1.2.1、分词器工作的过程 内置的分词器效果都不好,那怎么办?只能自己写了!在写之前当然是要先看看内置的分词器是怎么实现的了。
1236 0