【问题标题】:Is it possible to add custom metadata to a Lucene field?是否可以将自定义元数据添加到 Lucene 字段?
【发布时间】:2011-02-09 16:28:28
【问题描述】:

我已经到了需要在我的 Lucene.Net 索引中存储一些关于特定字段来自何处的附加数据的地步。具体来说,我想在将字段添加到文档时将 guid 附加到文档的某些字段,并在从搜索结果中获取文档时再次检索它。

这可能吗?

编辑: 好吧,让我通过一个例子来澄清一下。

假设我有一个对象,我希望允许用户使用“个人”、“收藏”、“某些项目”等自定义标签进行标记。我通过在文档中添加多个“标签”字段来做到这一点,如下所示:

doc.Add( new Field( "tag", "personal" ) );
doc.Add( new Field( "tag", "favorite" ) );

问题是我现在需要记录一些关于每个单独标签本身的元数据,特别是表示该标签来自哪里的 guid(想象它是一个用户 ID)。每个标签都可能有不同的 guid,所以我不能简单地创建一个“tag-guid”字段(除非保留值的顺序 --- 请参阅下面的编辑 2)。我不需要对这个元数据进行索引(实际上我不希望它被索引,以避免对元数据的影响),我只需要能够从文档/字段中再次检索它。

doc.GetFields( "tag" )[0].Metadata...

(我在这里编造语法,但我希望我的意思现在很清楚。)

编辑 2: 由于这是一个完全不同的问题,我针对这种方法发布了一个新问题:Is the order of multi-valued fields in Lucene stable?

好的,让我们尝试另一种方法...关键问题区域是同一字段名称下的多个字段值的不确定性(例如“标签”)。如果我可以在这里引入或获得某种确定性,我也许可以将元数据存储在另一个字段中。

例如,如果我可以依赖从不改变的字段值的顺序,我可以使用一组值中的索引来准确识别我指的是哪个标签。

当我稍后检索文档时,是否可以保证将值添加到字段的顺序保持不变?

【问题讨论】:

  • 你能把它添加到你的文档中吗:document.Add(new Field("GUID", "guidvalue", Field.Store.YES, Field.Index.NO));
  • @Prescott 问题是我正在为同一个字段添加多个值(例如“标签”),我需要跟踪每个标签的某些来源信息,所以我没有办法添加一个新字段来跟踪它,因为我无法唯一识别它们。
  • @chaiguy 我很难完全理解你的意思——你能举出一个超级简单的例子吗?
  • @chaiguy Prescott 是对的,您可以将多个字段添加到文档中,仅用于存储 - 这是一种常见做法
  • 试图在这里澄清:假设以下定义 Document { DocId, Text, Author, CreatedDate }。您是说您还想向各个字段添加其他数据。在这种情况下,假设您想使用 GUID 标记作者,因此为此文档添加一个新字段 AuthorGUID?

标签: lucene metadata lucene.net


【解决方案1】:

根据您对该索引的搜索要求,这可能是可能的。这样您就可以控制字段的顺序。当然,这需要随着标签列表的变化而更新这两个字段,但开销可能是值得的。

doc.Add(new Field("tags", "{personal}|{favorite}")); 
doc.Add(new Field("tagsref", "{1234}|{12345}")); 

注意:使用 {} 可让您在存在相似值的情况下限定搜索的唯一性。

示例:如果将值存储为“person|personal|personage”,搜索“person”将返回包含 person、personal 或 personage 之一的文档。通过像这样在大括号中限定:“{person}|{personal}|{personage}”,我可以搜索“{person}”并确保它不会返回误报。当然,这假设您没有在值中使用大括号。

【讨论】:

  • 这就是我最终要做的。您能否进一步解释 {} 字符的含义?这是否只是用于搜索或存储字段数据(正如您所做的那样)?
  • 更新了更多关于大括号的细节。
【解决方案2】:

我想你是在问payloads

编辑:从您的用例来看,您似乎不想在搜索中使用此元数据,您只是想要它。 (基本上,您希望将 Lucene 用作数据库系统。)

那么,为什么不能使用二进制字段呢?

ExtraData ed = new ExtraData { Tag = "tag", Type = "personal" };
byte[] byteData = BinaryFormatter.Serialize(ed); // this isn't the correct code, but you get the point
doc.Add(new Field("myData", byteData, Field.Store.YES));

然后你可以在检索时反序列化它。

【讨论】:

  • 这似乎对权重更有用,因为格兰特正在使用它。我可以看到如何扩展它以标记数据片段,但它似乎与字段本身内的特殊处理更相关(即“文本数据”->“文本|10 数据|5”-添加不同的权重。在这个情况下,我认为他想要“文本数据”|GUID 之类的东西 - 以便 GUID 指的是整个字段,而不是字段的片段,而不是整个文档
  • 我简要浏览了该页面,但负载似乎方式太复杂了,无法满足我的需要。看来我必须编写一个完全自定义的分析器并手动生成令牌流。
  • 我对这些提升很好奇,不过......是否可以分割字段的字符串值,以便我可以附加元数据并为其分配 0 提升,这样它将是被查询忽略?标准分析器是否支持这一点,还是我必须使用另一个/编写自己的?
  • @chaiguy:我已经编辑了我的答案:这就是你要找的东西吗?
  • 你是对的,我不想在搜索中使用元数据,但我确实希望能够使用该字段的值(例如标签)在搜索中。我已经用另一种方法更新了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多