Lucene使用DeleteDocuments删除索引无效的原因

2/10/2017来源:ASP.NET技巧人气:1111

今天使用Lucene的DeleteDocuments删除索引代码执行了,但是却还能搜索到该索引

这下面的代码看一点错误都没有,执行了但是却没有真正的删除索引

public static void DelSingleIndex(Analyzer analyzer, bool b, string path)
        {
            DirectoryInfo dirInfo = Directory.CreateDirectory(path);
            LuceneIO.Directory directory = LuceneIO.FSDirectory.Open(dirInfo);
            IndexWriter writer = new IndexWriter(directory, analyzer, b, IndexWriter.MaxFieldLength.LIMITED);
            writer.DeleteDocuments(new Term("Id", "-1000"));
            writer.Optimize();
            writer.Close();
        }
搞了半天才明白删不掉的原因是我添加的代码Id这个字段做了分词处理,代码如下

 public static void AddSingleIndex(Analyzer analyzer, bool b, string path)
        {
            DirectoryInfo dirInfo = Directory.CreateDirectory(path);
            LuceneIO.Directory directory = LuceneIO.FSDirectory.Open(dirInfo);
            IndexWriter writer = new IndexWriter(directory, analyzer, b, IndexWriter.MaxFieldLength.LIMITED);
            Document doc = new Document();
            doc.Add(new Field("Id", "-1000", Field.Store.YES, Field.Index.NOT_ANALYZED));//存储且索引
            doc.Add(new Field("Title", "最新的特朗普测试", Field.Store.YES, Field.Index.ANALYZED));//存储且索引
            doc.Add(new Field("Content", "123456789", Field.Store.YES, Field.Index.ANALYZED));//存储且索引
            doc.Add(new Field("PubDate", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), Field.Store.YES, Field.Index.NO));//存储且不需要索引
            doc.Add(new Field("LinkUrl", "testlink", Field.Store.YES, Field.Index.NO));//存储且不需要索引

            writer.AddDocument(doc);
            writer.Optimize();
            writer.Close();
        }
这里只要将以下代码

doc.Add(new Field("Id", "-1000", Field.Store.YES, Field.Index.ANALYZED));//存储且索引改为

doc.Add(new Field("Id", "-1000", Field.Store.YES, Field.Index.NOT_ANALYZED));//存储不分词且索引就是因为这个参数设置错误导致的

还有种情况就是下面的代码设置也会导致删除不成功,代码如下

doc.Add(new Field("Id", "-1000", Field.Store.YES, Field.Index.NO));因为Lucene在删除索引时要求删除对应的Field不能分词只能是一个词,而且这个Filed必须索引过

还有个注意点是在删除时使用Term时的原理是先去搜索满足条件的记录然后将所有满足的记录删除,所以官方也建议最好自己定义一个唯一标识来删除,比如我这边用的是自己定义的Id,而没有用Title,还比如新闻编号,产品编号等等