2010-07-28 32 views
1

我有一个模型,它看起来像这样:在GAE中使用python进行子串搜索?

class Search (db.Model) : 

word = db.StringProperty() 

一个例子“字”可以像字=“thisisaword”

我要搜索在搜索所有实体像子“本”“ isa“等。

如何在使用python的App引擎中执行此操作?

更新:

的位置的话将是域名。所以有一些限制,我想这个词的大小。例如google.com,facebook.com

我想显示“google.com”,当有人搜索“斗争”

回答

6

由于没有字的分离,我不认为你想要的任务是可行的(它会在许多数据库引擎中隐式地使用任何索引并破坏性能和可伸缩性,但App Engine并未实现不可避免地破坏可伸缩性和性能的“特性”)。如果你有话分离,您可以使用残留的全文检索解释here,但是,该博客说,

它没有精确短语匹配, 串匹配,布尔运算符, 而产生,或其他普通全文 功能。

nonrel-search由同一作者提到here为“另类”和“相似”的年纪大了,现在已经停产的项目称为gae-search(这是提供免费和付费版本 - 也许是需要付费的版本可以帮助你,我从来没有深入调查过它 - 我给出的最后一个链接有作者的联系信息,如果你的预算足够资助像这样昂贵的项目,他们可能很乐意为你开发一些东西) 。

问题是每个给定字符串的子字符串的数量与字符串的长度成正比增长,因此需要用于快速搜索所需的无限种类的索引也会非常快速地增长。如果对存储的字符串和搜索的字符串的长度有限制,则可以应用一些优化,但要解决任何半路可容忍的效率仍然是一个相当困难的问题。

也许你可以用这个假设的“任意子字符串搜索”来准确解释你想要获得什么,这样就可以评估字符串(和被搜索的子字符串)的数值限制。或许你想解决的确切问题,如果你的数字限制不严格(正如你目前表达你的问题,似乎没有任何限制 - 但希望情况并非如此!),可能并不实际可以解决的,但也许它的一些变体/子集可能......但是你需要解释有问题的确切问题,以允许帮助考虑这样的子集和变体!

编辑:给定一个轻微的澄清他的Q的OP的编辑,我会建议的启发是要挑选一些明智的最大值和最小值“相关子长度”(比如2和5,打电话给他们MINRSL和MAXRSL为定性)。当输入一个字符串(域名)时,如果合适的话,按点分解它(例如,你不希望允许搜索“遍布”这些点),可能会丢弃一些部分(你不想明确记录所有的后缀,你是否明确记录了所有的后缀?无论如何,这个决定是应用程序特定的),并且,对于做的其他部分希望可搜索,请为长度为MINRSL到MAXRSL的子字符串做一些索引。

具体而言,使用上面给出的限制2和5,并且假设www..com可以被移除(很像通常在全文搜索中移除诸如“和”,“the”,“of” :这样的“停用词”太常见了,寻找它们 - 换取索引它们的巨大代价 - 将返回无用的吨无关文件),您将不得不考虑作为可索引文件:

go oo og gl le 
goo oog ogl gle 
goog oogl ogle 
googl oogle 

因此,您需要创建一个模型的5 + 4 + 3 + 2 = 14个实例,该模型的可索引为一个字段,而另一个字段则为您存储实例的引用www.google.com。与所有索引方案一样,当然,这使得“写入”(创建新对象,或者更糟糕的是,改变现有索引的索引部分!)成为非常快速“读取”(搜索)的代价, 。

或者,更便宜的写作,但价格昂贵阅读(搜索),您可以记录只在一定单根长度的字符串,说4 - 这将是刚(理想情况过于简单,见下文):

goog oogl ogle 

即所述辅助模型的三个实例,而不是十四个。但是现在,为了搜索,你需要将被搜索的子字符串截断为四个字符,获得包含一些误报的所有匹配,并在应用程序中使用额外的代码来过滤可能的匹配,从而消除错误阳性。

当一个较短的字符串用户搜索,说只是“OO”,你可以找到与“OO”开始的所有比赛(同时使用一个>=和搜索一个<>=“OO” ,而且<“op”,下一个可能的长度 - 两个字符串)。但是,这是上述段落过于简单化,对于长度为4的子字符串的开始中未出现的较短子字符串搜索不适用 - 因此,您必须添加“尾随索引”

gle le 

(总共5个,而不是14个全索引)到这个更复杂但更均衡的方案。请注意,在另一个完整模型中,您需要使用代码来消除在需要时的误报 - 如果您将MAXRSL设置为5,并且用户查找长度为7的子字符串,例如7 ,你要么给出错误,要么将它截断为5,并应用上面提到的相同代码。

您能否提供更简单,更快速的“从MINRSL到MAXRSL”架构的完整索引?这取决于你的号码。如果你总共有大约2000个索引的URL,其索引中总共有4,000个“单词”,为了简单起见,我们会说所有的长度为8个字符,MINRSL = 2,MAXRSL = 5 scheme每个单词需要7 + 6 + 5 + 4个可索引词,即每个单词22个,乘以4,000只有88,000个条目,这将是相当实惠的。但是,如果你有更多的单词需要索引,或者大量更长的单词,或者需要更多的从最小到最大RSL的范围,那么这些数字会变得令人担忧(并且这种情况下可以节省一些因素三,为更复杂的慢搜索计划,可能被认为是值得的)。你不给我们任何数字,所以当然我不能猜测。

正如你所看到的,即使这个简单的想法导致需要非常复杂的代码 - 你不可能找到已经可用的开源代码,因为需求是非常奇怪的(很少有人关心“任意的DNS子串姓名“) - 从我的建议来看,除非你有信心在内部开发和调整所有这些代码,否则你可以考虑联系上述专业人士来获得为你开发这样的代码的报价(当然,你必须给他们你没有给我们的数字,包括允许辅助指数有多大,以便让他们在根据你的要求进行招标之前做出初步的可行性评估)。

+0

感谢您的详细分析。我已经更新了问题陈述。 – demos 2010-07-28 04:48:05

+1

您不需要很多模型实例 - 只是包含所有索引字符串的列表。考虑到您可以通过查询范围来进行前缀匹配,因此不需要索引任意子字符串 - 只是原始字符串的每个后缀。 – 2010-07-28 08:50:39

+0

@尼克,你如何“查询一个范围”索引字符串的列表?考虑到如果**任何**小于“op”,如果列表中的任何**项为“oo”或以后,则'> ='oo''将为真,并且'<'op'',则所谓的“范围”和“那些对我来说似乎是疯狂拥挤的假阳性。你是否可以用伪代码发布一个单独的答案来阐明你的意思是如何使用列表和范围查询? TIA尼克! – 2010-07-28 20:27:21