【问题标题】:How are efficient consecutive word searches implemented?如何实现高效的连续词搜索?
【发布时间】:2010-10-07 20:43:58
【问题描述】:

搜索引擎和数据库允许您使用连续的字符串搜索(例如"this is a test"),它匹配this is a test that will match,但不会匹配test this is a

我知道有些数据库具有内置功能,允许您使用相同的功能而无需编写任何代码(例如 MySQL 的全文搜索)。这不是我要寻找的答案。

我想知道的是使用什么样的算法和数据库结构来实现这种快速的字符串搜索。

在上面的示例中,索引表会是什么样子?会不会是类似的东西?

// IndexedItemID | Position | Word
1 | 0 | this
1 | 1 | is
1 | 2 | a
1 | 3 | test
1 | 4 | that
1 | 5 | will
1 | 6 | match
2 | 0 | test
2 | 1 | this
2 | 2 | is
2 | 3 | a

既然有索引项,那么如何有效地创建与这些项匹配的 SQL 语句?

这是我能想到的一个例子:

select IndexedItemID form
  (select IndexedItemID, Position from indexedWords where Word = "this") as word1Position
where
  exists(select * from indexedWords where IndexedItemID = word1Position.IndexedItemID AND Word = "is" AND Position = word1Position.Position + 1)
  AND exists(select * from indexedWords where IndexedItemID = word1Position.IndexedItemID AND Word = "a" AND Position = word1Position.Position + 2)
  AND exists(select * from indexedWords where IndexedItemID = word1Position.IndexedItemID AND Word = "test" AND Position = word1Position.Position + 3)

我确信可能有更标准化的方式更有效。

【问题讨论】:

  • MySQL的全文索引是开源的afaik,所以下载并找出:)

标签: algorithm database-design search


【解决方案1】:

您可能想查看Trie。它们在这样的场景中非常高效,但会消耗大量内存来存储整个结构。

【讨论】:

    【解决方案2】:

    您想要的是文档中单词的排序倒排索引。基本上如果你的文字是

    “这是一个例句。这就是你索引事物的方式”你把它变成:

    Here: 1
    is: 2, 7
    an: 3
    example: 4
    ......
    ......
    

    然后,当您搜索单词序列时,您会查找每个单词的位置列表。现在你想同时遍历排序位置的列表,就好像你试图合并列表一样。在合并列表时,很容易发现单词列表以您希望的确切顺序出现的任何地方。

    【讨论】:

      【解决方案3】:

      我不确定 sql 数据库如何缩小搜索范围,但最终会归结为字符串匹配。

      当您有一个目标字符串和一个模式字符串时,进行比较的最简单方法是从目标字符串的开头开始,并尝试将其与模式字符串逐个字符地进行匹配。如果匹配失败,则前进到目标字符串中的下一个字符并重复上述步骤。这显然是低效的,因为复杂度为 O(m*n),其中 m 是模式字符串中的字符数,n 是目标字符串中的字符数。

      有一种称为Rabin-Karp algorithm 的算法可以使用散列在 O(m+n) 中执行此搜索。

      当然,mysql 可以计算出有助于减少目标字符串数量的哈希值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-10
        • 2012-04-19
        • 1970-01-01
        • 2021-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多