【问题标题】:Efficient index for strings to do full text indexing字符串的高效索引以进行全文索引
【发布时间】:2012-05-16 17:50:26
【问题描述】:

我正在寻找一种数据结构来解决以下问题。接收大量相当短的字符串(例如 5000 万,少于 30 个字符)作为输入,并根据需要对它们进行索引。然后,回答我给出一个新字符串的查询,并且您提供与提供的字符串相似的初始集合中的字符串(例如,10 个最好的此类字符串)。理想情况下,“相似性”的概念类似于编辑距离或 Jaro-Winkler 距离,或其近似值,但它应该能够适应拼写和词序的微小变化,以及添加垃圾词。 (例如,与标准索引任务不同,如果请求“foo bar”确实是集合中最接近的字符串,则它应该产生“foo”)。

举个例子,假设字符串集合是 {"Charles Dickens", "Mary Shelley", "Robert Stephenson"}。查询“狄更斯,查尔斯”应该找到“查尔斯狄更斯”。查询“by Shelley”应该返回“Mary Shelley”。

逐一计算查询字符串与集合中所有字符串的相似度的简单方法对于大型集合来说太慢了。什么是更有效地回答此类查询的好数据结构?理想情况下,我会寻找一个好的 Java 实现。

【问题讨论】:

  • 你在找Apache Lucene
  • 这与拼写检查器在建议可能的更正时所做的非常相似。您可能想检查他们实际上是如何做到的。
  • 我不认为 Lucene 可以,因为诸如“foo bar”甚至“foop bar”之类的查询返回“foo”的限制。我不想只在单词级别进行比较,也不想要求 all 查询单词出现。另外,我希望对任意编辑具有弹性,我不确定 Lucene 是否能够做到。
  • 第一个近似值是“KWIC 索引”。
  • Lucene 绝对有能力(几乎)做任何你能想象到的事情。您的示例属于 Lucene 功能的微不足道的范围。请记住,Lucene 是一个 API,特定于您的要求的功能的实现掌握在您手中。 Lucene 只是完成这项工作的艰难部分的工具。

标签: java string algorithm data-structures indexing


【解决方案1】:

想到两个建议:

1) 选择一个满足三角不等式的距离函数并使用 http://en.wikipedia.org/wiki/Cover_tree - 可能会提供一些加速,但可能不是数量级。

2) 猜测最接近的匹配将包括至少一段 k 个连续字符,这是两个字符串之间的完全匹配。构建一个数据结构,例如使用哈希表查找可以找到集合中的所有字符串,这些字符串至少具有与查询字符串的某些部分相同的 k 个连续字符,然后使用您的距离函数查看从中返回的哪些字符串是最佳匹配。应该很快,但有时会错过正确的答案。

【讨论】:

    【解决方案2】:

    作为您琐碎方法的替代方法,您可以分两步解决问题:

    1. 建立一个出现在所有字符串中的单词的索引,它允许您找到包含给定单词的句子。这应该远小于 5000 万(如果我们谈论的是自然语言)。而且您可能不关心“foop bar”->“foo”,因为您只有单词。
    2. 将查询拆分为单词。对于每个单词,找到包含该单词的所有句子。对于每个句子,使用您的指标计算与查询字符串的相似度。

    另一个好处是,在许多情况下,您可以在不重建单词索引的情况下更改指标。

    【讨论】:

    • 我确实关心“foop bar”->“foo”,因为可能存在拼写错误和拼写变化,或者说,“foo_bar”与“foo bar”。拆分成单词是个好主意,比简单的方法更好,但不够健壮。
    猜你喜欢
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 2021-04-08
    • 2019-06-10
    • 2011-12-25
    • 2016-06-16
    相关资源
    最近更新 更多