高性能分层文本搜索

时间:2009-12-30 23:07:42

标签: database performance database-design search hierarchy

2 个答案:

答案 0 :(得分:3)

看看Apache Lucene。您可以使用Lucene实现非常灵活且高效的搜索。它可能很有用。

另请参阅搜索模式 - 您所描述的内容可能适用于分面搜索模式。

很容易实现一个简单的“Aaron House Living Door”算法,但不能确定基于SVM /分类/熵的常规算法可以扩展到大型数据集。您可能还想看看Motwani和Raghavan的“近似搜索”概念。

如果可能,请回复您找到的内容: - )

答案 1 :(得分:3)

嗨Aarron,我有以下想法:
根据您的描述,我的脑海中有以下图像:

          Aaron
         /     \
        /       \
       /         \
  House           Cars
    |            /    \
Living Room   Ferrari  Mercedes
    |
Liquor Cabinet
    /    |    \
Table   Door   Window

这就是搜索树的外观。现在我将对每个级别的节点进行排序:

               Aaron
              /     \
             /       \
            /         \
         Cars         House
         /   \       /
        /     \     /
       /       \   /
      /         \ /
     /           X
    /           / \
   /           /   \
  /           /     \
 /           /       \
|           /         \
|          /           \ 
Ferrari   Living Room   Mercedes
                        |
                  Liquor Cabinet
                   /    |    \
               Door   Table   Window

现在处理查询应该简单快捷:

  1. 从查询中的最后一个单词开始,最低节点级别(叶子)
  2. 由于所有节点都在一个级别内排序,因此您可以使用二进制搜索,因此在O(日志N)时间内找到匹配项,其中N是节点数。
  3. 为每个级别执行此操作。树中有O(log N)级别。
  4. 找到匹配项后,处理所有父节点以查看路径是否与您的查询匹配。路径长度为O(log N)。如果匹配,则将其存储在结果中,该结果应显示给用户。
  5. 设M为总匹配数(与查询中最后一个字匹配的节点数)。然后我们的处理时间是:O((log N)^ 2 + M *(log N)):
    二进制搜索每个级别需要O(log N)时间并且存在O(log N)级别,因此我们必须花费至少O((log N)^ 2)时间。现在,对于每个匹配,我们必须测试从匹配节点到根的完整路径是否与完整查询匹配。路径长度为O(log N)。因此,给定M匹配总体,我们花费另一个M * O(log N)时间,因此得到的执行时间是O((log N)^ 2 + M *(log N))。

    当你的匹配很少时,处理时间接近O((log N)^ 2),这是非常好的。相反,如果发生最坏情况(每个路径与查询匹配(M = N)),则处理时间接近O(N log N),这不是太好,但也不太可能。

    <强>实施 你说,你只想要一个想法。我对数据库的了解非常有限,所以我在这里写的不多,只是概述一些想法 节点表可能如下所示:

    • ID:int
    • 文字:字符串
    • 父级:int - &gt;节点ID
    • 级别:int //我不希望这种情况经常发生变化,因此您可以保存并更新它,因为数据库会发生变化。

    此表必须按“文本”列进行排序。使用上述算法,循环内的sql查询可能如下所示:
    SELECT ID FROM node WHERE Level = $i AND Text LIKE $text
    希望能得到我的观点。

    不仅可以通过“文本”列对表进行排序,而且通过组合的“文本”和“级别”列,即Level = 20中的所有条目排序,所有条目都可以加快速度在Level = 19排序等内(但不需要对整个表进行整体排序)。但是,节点计数PER LEVEL是O(N),因此没有渐近的运行时改进,但我认为值得尝试,考虑到你实际存在的较低常数。

    编辑:改进

    我刚注意到,迭代算法是完全没必要的(因此可以放弃水平信息)。完全足够:

    1. 按文字值
    2. 存储所有节点
    3. 使用所有节点上的二进制搜索,一次查找查询的最后一个单词的所有匹配项。
    4. 从每个匹配项中,跟踪路径到根目录,并检查路径是否与整个查询匹配。
    5. 这将运行时间改进为O(log N + M *(log N))。