如何更新 lucene.net 索引中的字段而不是更新所有索引的示例

example for how to update a field in lucene.net index instead update all index

我在网络中使用 Lucene.net 创建搜索引擎 Api ,我发现了一个 CRUD 像这样更新索引的代码

 private void CRUDIndex()
        {
            Video_List video = new Video_List();

            FSDirectory directory = FSDirectory.Open(new DirectoryInfo(Path), new NativeFSLockFactory());
            bool isExist = IndexReader.IndexExists(directory);
            if (isExist)
            {
                if (IndexWriter.IsLocked(directory))
                {
                    IndexWriter.Unlock(directory);
                }
            }
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isExist, IndexWriter.MaxFieldLength.UNLIMITED);
            while (bookQueue.Count > 0)
            {
                Document document = new Document();
                BookViewMode book = bookQueue.Dequeue();
                if (book.IT == IndexType.Insert)
                {
                    document.Add(new Field("id", book.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                    document.Add(new Field("title", book.Title, Field.Store.YES, Field.Index.ANALYZED,
                                           Field.TermVector.WITH_POSITIONS_OFFSETS));
                    document.Add(new Field("content", book.Starring, Field.Store.YES, Field.Index.ANALYZED,
                                           Field.TermVector.WITH_POSITIONS_OFFSETS));
                    writer.AddDocument(document);
                }
                else if (book.IT == IndexType.Delete)
                {
                    writer.DeleteDocuments(new Term("id", book.ID.ToString()));
                }
                else if (book.IT == IndexType.Modify)
                {
                    writer.DeleteDocuments(new Term("id", book.ID.ToString()));
                    document.Add(new Field("id", book.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                    document.Add(new Field("title", book.Title, Field.Store.YES, Field.Index.ANALYZED,
                                           Field.TermVector.WITH_POSITIONS_OFFSETS));
                    document.Add(new Field("content", book.Starring, Field.Store.YES, Field.Index.ANALYZED,
                                           Field.TermVector.WITH_POSITIONS_OFFSETS));
                    writer.AddDocument(document);
                }
            }
            writer.Dispose();
            directory.Dispose();
        }

它就像在删除旧索引后添加一个新索引,但我只想更新字段并将其添加到旧索引中,而且我不知道如何 return 到 api 控制器更新索引,所以有没有人可以给我一些提示或更好的演示给我看。我会很感激帮助!

据我所知,你不能。不过,还有一个更方便的方法,UpdateDocument(Term, IEnumerable<IIndexableField>).

else if (book.IT == IndexType.Modify)
{
    document.Add(new Field("id", book.ID.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
    document.Add(new Field("title", book.Title, Field.Store.YES, Field.Index.ANALYZED,
                           Field.TermVector.WITH_POSITIONS_OFFSETS));
    document.Add(new Field("content", book.Starring, Field.Store.YES, Field.Index.ANALYZED,
                           Field.TermVector.WITH_POSITIONS_OFFSETS));
    writer.UpdateDocument(new Term("id", book.ID.ToString()), document);
}

索引并不意味着是数据库,它是一个可以添加数据以使其非常快进行搜索的位置。

要利用 WebApi 的更新功能,您可以利用数据库更新(更新数据库中的字段、从数据库中读取整个记录、更新索引)。或者,如果您不需要实时执行搜索,您可以定期在批处理过程中更新索引。

如果您的数据更新速度非常快,并且您想对实时数据进行搜索,则有两种选择:

  1. 使用 IndexWriter 提供的 Near Real-time Search functionality 结合实时更新索引。
  2. 如果您愿意承受性能损失,您可以继承 Directory 并直接从您的数据库中读取数据。其他人已经完成了几个实现(您可以直接使用或反向工程)- LuceneNetSqlDirectory (NuGet) and AzureDirectory (NuGet)。如果你这样做,你可以用传统的方式更新数据源中的数据。