数据库 – 高性能分层文本搜索

前端之家收集整理的这篇文章主要介绍了数据库 – 高性能分层文本搜索前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我现在正处于升级主要交易系统中的层次结构设计的最后阶段,我已经在这150行查询中盯着我看了一段时间(我将免除你阅读的所有麻烦)并认为那里必须是一个更好的方式.

该问题的快速摘要如下:

您将如何实现层次结构搜索,该搜索匹配层次结构中不同级别的多个搜索项,并针对最快的搜索时间进行了优化?

我找到了一个somewhat related question,但它实际上只有我实际需要的答案的20%左右.这是完整的场景/规范:

>最终目标是在层次结构中的任意位置找到一个或多个任意项.
>完整的层次结构大约有80,000个节点,预计在几年内会增长到1M.
>层次结构中整个路径的全文是唯一且具有描述性的;但是,单个节点的文本可能不是.这是一个商业现实,而不是一个轻率的决定.
>示例:一个节点可能有一个像“门”这样的名字,这本身就没有意义,但完整的背景,“Aaron> House> Living Room> Liquor Cabinet> Door”,有明确的含义,它描述了一个特定位置的特定门. (请注意,这只是一个例子,真正的设计远没那么简单)
>为了找到这个特定的门,用户可能会输入“aaron酒门”,这可能只会产生一个结果.查询被翻译为序列:包含文本“door”的项目,在包含文本“liquor”的项目下,在包含文本“aaron”的另一项目下.
>或者,用户可能只需键入“家酒”就可以列出人们家里的所有酒柜(这不是很好).我明确提到这个例子,表明搜索不需要匹配任何特定的根或叶级别.这个用户确切地知道他正在寻找哪个门,但不记得谁拥有它,并且会记住这个名字是否出现在他面前.
>所有术语必须按指定的顺序匹配,但正如上面的示例所示,层次结构中的级别可以“跳过”.术语“aaron booze cabinet”与此节点不匹配.
>该平台是sql Server 2008,但我认为这是一个独立于平台的问题,并且不希望限制该平台的答案.
>层次结构本身基于hierarchyid(物化路径),索引广度优先和深度优先.每个层次结构节点/记录都有一个要查询的Name列.基于节点的层次结构查询非常快,因此不必担心这些问题.
>没有严格的层次结构 – 根可能根本不包含任何节点,或者可能包含扇出到10,000个叶节点的30个子树.
>最大嵌套是任意的,但实际上它往往不超过4-8级.
>虽然不经常,但层次结构可以而且确实会发生变化.任何节点都可以移动到任何其他节点,但有明显的例外(父节点不能移动到自己的子节点等)
>如果还没有暗示:我确实可以控制设计,可以添加索引,字段,表格,以及获得最佳结果所需的一切.

我的“梦想”是向用户提供即时反馈,如渐进式搜索/过滤器,但我知道这可能是不可能的或非常困难的.我对当前方法的任何重大改进感到满意,通常需要0.5s到1s,具体取决于结果的数量.

为了完整起见,现有查询(存储过程)首先收集包含最终术语的所有叶节点,然后向上连接并排除其路径与先前术语不匹配的任何路径.如果这对任何人来说都是落后的,那么请放心,这比从根源开始并散开更有效率.这是“旧的”方式,每次搜索可能需要几秒钟.

所以我的问题再次出现:是否有更好(更有效)的方式来执行此搜索

我不一定在寻找代码,只是方法.我考虑了一些可能性,但它们似乎都有一些问题:

>创建一个分隔的“路径文本”列,并使用全文搜索对其进行索引.麻烦的是,对此列的搜索也将返回所有子节点; “aaron house”也与“aaron house kitchen”和“aaron house basement”相匹配.
>创建了一个NamePath列,它实际上是一个嵌套的字符串序列,使用CLR类型,类似于hierarchyid本身.问题是,我不知道微软如何能够将这种类型的查询“转换”为索引操作,我甚至不确定它是否可以在UDT上进行.如果最终结果只是一个完整的索引扫描,我就没有通过这种方法获得任何收益.

如果我不能做得比现有的更好,那真的不是世界末日;搜索“相当快”,没有人抱怨它.但是我愿意打赌以前有人已经解决了这个问题并且有一些想法.请分享一下!

解决方法

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

另请参阅搜索模式 – 您所描述的内容可能适合分面搜索模式.

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

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

猜你在找的MsSQL相关文章