1 public sealed class SearchIndexManager 2 { 3 private static readonly SearchIndexManager searchManager=new SearchIndexManager(); 4 private SearchIndexManager() 5 { 6 7 } 8 public static SearchIndexManager GetSingleSearchManager() 9 { 10 return searchManager; 11 } 12 private Queue<SearchContent> indexQueue = new Queue<SearchContent>(); 13 /// <summary> 14 /// 添加索引 15 /// </summary> 16 public void AddIndex(SearchContent indexContent) 17 { 18 indexContent .IndexType =CreateIndexEnum .Add; 19 indexQueue.Enqueue(indexContent); 20 } 21 /// <summary> 22 /// 删除索引 23 /// </summary> 24 /// <param name="indexContent"></param> 25 public void DeleteIndex(SearchContent indexContent) 26 { 27 indexContent .IndexType =CreateIndexEnum .Delete; 28 indexQueue .Enqueue (indexContent); 29 } 30 //没输入一条数据就添加相应的索引,为了解决锁的问题,使用队列的方式,向队列中添加数据,接下来就是从队列中取出数据,添加到lucen的索引库中 31 public void StartIndexThread() 32 { 33 Thread thread = new Thread(new ThreadStart(CreateIndex)); 34 thread.IsBackground = true; 35 thread.Start(); 36 } 37 public void CreateIndex() 38 { 39 while (true) 40 { 41 if (indexQueue.Count > 0) 42 { 43 //创建索引 44 //将创建的分词内容放在该目录下 45 string indexPath = @"D:\LuceneDir"; 46 //为Lucent.net指定索引文件(打开索引目录) FS指的是就是FileSystem 47 FSDirectory directory = FSDirectory.Open(new DirectoryInfo(indexPath), new NativeFSLockFactory()); 48 //IndexReader:对索引进行读取的类。该语句的作用:判断索引库文件夹是否存在以及索引特征文件是否存在。 49 bool isUpdate = IndexReader.IndexExists(directory); 50 if (isUpdate) 51 { 52 //同时只能有一段代码对索引库进行写操作。当使用IndexWriter打开directory时会自动对索引库文件上锁。 53 //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁(提示一下:如果我现在正在写着已经加锁了,但是还没有写完,这时候又来一个请求,那么不就解锁了吗?这个问题后面会解决) 54 if (IndexWriter.IsLocked(directory)) 55 { 56 IndexWriter.Unlock(directory); 57 } 58 } 59 //向索引库中写索引。这时在这里加锁。同时指定分词算法是盘古分词 60 //通过writer会将索引写到我们制定的文件夹目录下 61 IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED); 62 63 //从队列中取出数据 64 SearchContent search= indexQueue.Dequeue(); 65 //我们需要添加到Lucene.net索引库的文件 66 Document document = new Document();//表示一篇文档。 67 //Field.Store.YES:表示是否存储原值。只有当Field.Store.YES在后面才能用doc.Get("number")取出值来.Field.Index. NOT_ANALYZED:不进行分词保存 68 //因为不会进行覆盖,所以需要将以前的打上删除标志,否则将会出现多个重复的 69 writer.DeleteDocuments(new Term("id", search.ID.ToString())); 70 71 if (search.IndexType == CreateIndexEnum.Delete) 72 { 73 continue; 74 } 75 document.Add(new Field("id", search.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); 76 77 //Field.Index. ANALYZED:进行分词保存:也就是要进行全文的字段要设置分词 保存(因为要进行模糊查询) 78 79 //Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS:不仅保存分词还保存分词的距离。 80 81 document.Add(new Field("title", search.Title, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS)); 82 document.Add(new Field("content", search.Content , Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS)); 83 writer.AddDocument(document); 84 85 writer.Close();//会自动解锁。 86 directory.Close();//不要忘了Close,否则索引结果搜不到 87 } 88 else 89 { 90 Thread.Sleep(5000); 91 } 92 } 93 }
原文:http://www.cnblogs.com/XZhao/p/7237243.html