【问题标题】:example for how to update a field in lucene.net index instead update all index如何更新 lucene.net 索引中的字段而不是更新所有索引的示例
【发布时间】:2017-05-23 14:24:00
【问题描述】:

我在 web Api 中使用 Lucene.net 创建了一个搜索引擎,我发现了一个 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();
        }

它就像删除旧索引后添加一个新索引,但我只想更新字段并将其添加到旧索引中,我不知道如何返回 api 控制器关于更新索引,所以有没有人可以给给我一些提示或更好的提示,向我展示演示。我将不胜感激!

【问题讨论】:

    标签: c# api indexing lucene.net


    【解决方案1】:

    AFAIK,你不能。不过,还有一种更方便的方法,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) 和 AzureDirectory (NuGet)。如果您这样做,您只需按照传统方式更新数据源中的数据。

    【讨论】:

    • 首先感谢您的详细解释,但是这部分 writer.UpdateDocument("id",document) 仍然存在一些错误,并报告无法从“Lucene.net.Documents”转换.Document”到“string”,其实这是我的论文题目,所以我只是想向大家展示lucene.net是如何工作的,包括更新索引,所以我的计划只是更新索引,并将结果显示为Json代码使用控制器,那么你能告诉我一个例子,通过使用这个更新方法,如何创建一个 POST 来返回这个方法的结果?
    • /*还有部分代码在CRUDIndex方法之前*/ public void StartNewThread() { ThreadPool.QueueUserWorkItem(newWaitCallback(QueueToIndex)); } private void QueueToIndex(object para) { while (true) { if (bookQueue.Count > 0) { CRUDIndex(); } 其他 { Thread.Sleep(3000); } } }
    • /*还有部分代码在CRUDIndex方法之前*/ public void StartNewThread() { ThreadPool.QueueUserWorkItem(newWaitCallback(QueueToIndex)); } private void QueueToIndex(object para) { while (true) { if (bookQueue.Count > 0) { CRUDIndex(); } 其他 { Thread.Sleep(3000); } } }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    相关资源
    最近更新 更多