使用Lucene.NET实现数据检索功能

摘要:
对数据进行索引,并使用索引技术更灵活、快速地实现检索功能。以下是我想在实际项目中介绍的Lucene的NET版本。该系统主要分为两部分。第一部分是索引管理,建立或更新文件索引;第二部分是文件检索,将关键字与索引数据库匹配并获取相关信息。因为Lucene是一项外国技术,它对中文分词的支持并不高。这里我建议使用盘古分词。1//指定索引库文件2FSDirectory=FSDirectory的文件位置。打开3//判断索引文件目录是否有4boolsExist=IndexReader。索引存在;5if6{7if8{9IndexWriter解锁;10}11}12//盘古分词器13PanGuAnalyzeranalyzer=newPanGuAnalyzer();14//索引写入类15IndexWriter=newIndexWriter(目录,分析器,!
  • 引言
    在软件系统中查询数据是再平常不过的事情了,那当数据量非常大,数据存储的媒介不是数据库,或者检索方式要求更为灵活的时候,我们该如何实现数据的检索呢?为数据建立索引吧,利用索引技术可以更灵活更快捷的实现检索功能。
    以下我要介绍的是.NET版的Lucene在实际项目中是如何应用的。
  • 案例概要
    我以一个文件检索系统为例,主要功能就是为硬盘中大量文件建立一个统一的检索平台,并且不使用数据库。
  • 思路
    该系统主要分为两部分,第一部分是索引的管理,为文件建立或更新索引;第二部分是文件的检索,根据关键词与索引库进行匹配并获得相关信息。这两部分功能可以整合在一个项目中,也可以分开在不同的项目中。
  • 分词
    需要注意的是不论是索引的管理还是文件的检索都离不开一样东西,那就是分词,正是分词的力量将多个关键字可以按照分词规则精确的与庞大的索引库进行匹配。 
    因为Lucene是国外的技术,所以对中文分词支持度并不高,这里我推荐使用盘古分词。
  • 索引的管理
    索引的管理主要是建立索引、更新索引和删除索引。需要注意的是用做识别的ID字段不能使用带有特殊符号的字符串,尽量使用词或者编号等,不然索引可能无法删除,也无法正常更新。
 1 //指定索引库文件存放文件位置
 2 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(this.IndexDataDir), new NativeFSLockFactory());
 3 //判断索引文件目录是否存在
 4 bool isExist = IndexReader.IndexExists(directory);
 5 if (isExist)
 6 {
 7     if (IndexWriter.IsLocked(directory))
 8     {
 9         IndexWriter.Unlock(directory);
10     }
11 }
12 //盘古分词器
13 PanGuAnalyzer analyzer = new PanGuAnalyzer();
14 //索引写入类
15 IndexWriter writer = new IndexWriter(directory, analyzer, !isExist, IndexWriter.MaxFieldLength.UNLIMITED);
16 //循环队列执行操作
17 while (IndexDataQueue.Count > 0)
18 {
19     Document document = new Document();
20 //这是我为索引数据自定义的模型类,主要内容是文件的路径、名称、内容和索引管理的操作类型(新增、更新、删除)
21     BaseDataMode mode = IndexDataQueue.Dequeue();
22     switch (mode.Type)
23     {
24         case OperationType.Insert:
25             {
26                 foreach (KeyValuePair<string, string> kv in mode.Content)
27                 {
28                     //这里kv.Key是设置索引内字段的名称,kv.Value是这个字段内存储的内容。
29                     document.Add(new Field(kv.Key, kv.Value, Field.Store.YES, Field.Index.ANALYZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
30                 }
31                 writer.AddDocument(document);
32             }; break;
33         case OperationType.Update:
34         {
35             //设置删除条件
36             MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, new string[] { "id" }, analyzer);
37             Query query = parser.Parse(mode.Content["id"]);
38             writer.DeleteDocuments(query);
39             foreach (KeyValuePair<string, string> kv in mode.Content)
40             {
41                 document.Add(new Field(kv.Key, kv.Value, Field.Store.YES, Field.Index.ANALYZED,Field.TermVector.WITH_POSITIONS_OFFSETS));
42             }
43             writer.AddDocument(document);
44         }; break;
45         case OperationType.Delete:
46         {
47             MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, new string[] { "id" }, analyzer);
48             Query query = parser.Parse(mode.Content["id"]);
49             writer.DeleteDocuments(query);
50         }; break;
51         default: { }; break;
52     }
53 }
54 //提交操作
55 writer.Commit();
56 //优化
57 writer.Optimize();
58 //关闭连接
59 writer.Close();
60 directory.Close();
  • 文件检索
    文件检索主要的过程是,先对查询的内容进行分词,将其分解为多个关键词,然后使用Lucene内置的搜索功能对已建好的索引库进行查询,最后将搜索结果显示出来。
 1 //指定索引库文件存放文件位置
 2 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(this.IndexDir), new NativeFSLockFactory());
 3 IndexReader reader = IndexReader.Open(directory, true);
 4 IndexSearcher searcher = new IndexSearcher(reader);
 5 //设置关键词在条件中为OR关系
 6 BooleanQuery queryOr = new BooleanQuery();
 7 foreach (string word in SplitContent.SplitByPanGu(keyword))
 8 {
 9     foreach (KeyValuePair<string, string> kv in Mode.Content)
10     {
11         TermQuery query = new TermQuery(new Term(kv.Key, word));
12         //这里设置条件为Or关系
13         queryOr.Add(query, BooleanClause.Occur.SHOULD);
14     }
15 }
16 //获取搜索结果       
17 //1000为搜索文件的下标限制,设置这个可以控制检索的范围,也可以用于分页显示
18 TopDocs tds = searcher.Search(queryOr, null, 1000);
19 ScoreDoc[] docs = tds.scoreDocs;
20 for (int i = 0; i < docs.Length; i++)
21 {
22     int docId = docs[i].doc;
23     Document doc = searcher.Doc(docId);
24 string content = doc.Get("索引内字段的名称");
25 }
26  
  • 资源

  DLL与词库:http://download.csdn.net/detail/aaakingwin/7208679

免责声明:文章转载自《使用Lucene.NET实现数据检索功能》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇IntelliJ Idea 授权服务器使用pip安装使用详解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

利用Elasticsearch搭建全球域名解析记录

前言 数据来源,由Rapid7收集并提供下载https://scans.io/study/sonar.fdns 下载Elasticsearch 2.3 ElasticSearch是一个基于Lucene开发的搜索服务器,具有分布式多用户的能力,ElasticSearch是用Java开发的开源项目(Apache许可条款),基于Restful Web接口,能够...

将json转换为数据结构体

主要用到的依赖:(划重点:这个依赖需要加jdk版本号,不加的话用不了,且目前最高是jdk15) (ps: 用于json与其他类型格式转换,JSONObject, JSONArray等来自这个包) <!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib -->...

单点登陆 ---密钥

一、需求描述 现在有A系统和B系统,需要在A系统进行单点登陆到B系统。 二、B系统要做事 1、提供一个可以让A系统登陆的网址 http://localhost:8083/Account/SingleSignOn/?u=xxx&token=FB92B341DBDB59D7 其中,u为加密后的用户名,token为B系统与A系统单点登录握手密钥 2、控制...

tips

史上最全的Unity面试题(持续更新总结。。。。。。) 包含答案的Unity面试题 这个是我刚刚整理出的Unity面试题,为了帮助大家面试,同时帮助大家更好地复习Unity知识点,如果大家发现有什么错误,(包括错别字和知识点),或者发现哪里描述的不清晰,请在下面留言,我会重新更新,希望大家共同来帮助开发者 一:什么是协同程序? 在主线程运行的同时开启另...

Mysql的索引

什么是索引: 数据库中的索引与书籍中的目录类似,在一本书中,利用目录可以快速查找所需要的信息,无需阅读整本书.在数据库中,索引使数据库程序无须对整个表进行扫描,就可以在其中找到所需数据.书中的目录是一个词语列表,其中注明了包含各个词的页码,在数据库中,由于数据存储在数据表中,因此索引是创建在数据表对象上的,由表中的一个字段或多个字段生成的键组成,这些键存储...

索引长度过长 ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

1.发现问题  今天在修改innodb表的某个列的长度时,报如下错误:   [html]view plaincopy  print? alter table test2 modify column id varchar(500);   ERROR 1071 (42000): Specified key was too long; max key ...