【问题标题】:Lucene calculate term vectors for existing indexLucene 计算现有索引的术语向量
【发布时间】:2022-06-11 03:46:16
【问题描述】:

对于 Lucene.net,我想获得 stackoverflow question 中描述的术语向量。

问题是,索引已经生成了索引和存储的字段,但没有术语向量。

FieldType type = new FieldType();
type.setIndexed(true);
type.setStored(true);
type.setStoreTermVectors(false);

理论上,应该可以重新计算每个文档的词向量,然后将其存储在索引中。

您知道在不删除完整 Lucene 索引的情况下如何做到这一点吗?

【问题讨论】:

  • 不是答案,只是一些注释:(1)我的注释是基于 Java 使用的,但应该可以翻译成 .NET。 (2) 您不能将缺失的词向量信息添加到现有索引中。您可以更新(替换)索引数据 - 但这是您想要避免的,我想。
  • (3) 您可以创建动态术语向量数据(不存储在索引中)。使用 TokenStream 类的 Add Attribute() 方法 - 例如,使用 OffsetAttribute 类。权衡是较小的索引(或不重新构建索引),但搜索速度可能较慢。
  • @andrewJames note (3) 非常有趣。我没有意识到这是可能的。希望我能以一种能让你获得更多积分的方式投票。老实说,我认为您的两个 cmets 值得合并为一个实际答案。
  • @andrewJames 如果您能提供一个示例并将其与实际答案结合起来,那将非常酷。

标签: lucene lucene.net


【解决方案1】:

正如我在问题中的 cmets 中所述,您可以即时生成术语向量数据,这可以帮助您避免完全重建索​​引数据。

在我的场景中,我想在匹配的文档中找到我的搜索词的偏移位置。

我不想夸大这种方法 - 它绝对不能替代重新索引 - 但如果您的查询是基本的,它可能会有所帮助。


第 1 步:执行您当前正在执行的任何查询。

对于命中列表中的每个文档,您将需要重新处理该文档中的相关字段 - 因此,您已经将字段数据存储在现有索引中,或者您需要从它的原始来源。


第 2 步:对于每个此类字段,您可以重复使用相同的分析器即时构建令牌流。令牌流可以配置不同的属性,例如:

  • 令牌属性
  • 偏移属性
  • 和其他人(见here

示例:

using Lucene.Net.Analysis.Standard;
using Lucene.Net.Analysis.TokenAttributes;
using Lucene.Net.Util;

const LuceneVersion AppLuceneVersion = LuceneVersion.LUCENE_48;

String? fieldName = null;
String fieldContent = "Foo Bar Baz Bar Bat";
String searchTerm = "bar";

var analyzer = new StandardAnalyzer(AppLuceneVersion);
var ts = analyzer.GetTokenStream(fieldName, fieldContent);
var charTermAttr = ts.AddAttribute<ICharTermAttribute>();
var offsetAttr = ts.AddAttribute<IOffsetAttribute>();

try
{
    ts.Reset();
    Console.WriteLine("");
    Console.WriteLine("Token: " + searchTerm);
    while (ts.IncrementToken())
    {
        if (searchTerm.Equals(charTermAttr.ToString())) 
        {
            var start = offsetAttr.StartOffset;
            var end = offsetAttr.EndOffset;
            Console.WriteLine(String.Format("  > offset: {0}-{1}", start, end));
        }
    }
    ts.End();
}
catch (Exception)
{

    throw;
}

以上示例假设第 1 步中的其中一个匹配项是包含 "Foo Bar Baz Bar Bat" 的字段 - 搜索词为 bar

生成的输出是:

Token: bar
  > offset: 4-7
  > offset: 12-15

因此,如您所见,您并没有重新执行查询 - 您只是重新处理令牌流。原始搜索词越复杂,就越难让这种方法按照您可能需要的方式工作。

【讨论】:

    猜你喜欢
    • 2013-02-13
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 2014-02-21
    相关资源
    最近更新 更多