Google app engine 应用程序引擎-轻松文本搜索

Google app engine 应用程序引擎-轻松文本搜索,google-app-engine,text-search,Google App Engine,Text Search,我希望为应用程序引擎实现一个简单但有效的文本搜索,在官方发布应用程序引擎文本搜索功能之前,我可以使用它。我看到有很多库,但是安装新的东西总是很麻烦。我想知道这是否是一个有效的策略: 1) 将需要进行文本搜索的每个属性分解为一组(列表)文本片段 2) 保存添加了这些列表的记录 3) 搜索时,只需在列表属性上使用相等筛选器 例如,如果我有记录: { firstName="Jon"; lastName="Doe"; } 我可以保存这样的财产: { firstName="Jon"; l

我希望为应用程序引擎实现一个简单但有效的文本搜索,在官方发布应用程序引擎文本搜索功能之前,我可以使用它。我看到有很多库,但是安装新的东西总是很麻烦。我想知道这是否是一个有效的策略:

1) 将需要进行文本搜索的每个属性分解为一组(列表)文本片段 2) 保存添加了这些列表的记录 3) 搜索时,只需在列表属性上使用相等筛选器

例如,如果我有记录:

{
  firstName="Jon";
  lastName="Doe";
}
我可以保存这样的财产:

{
  firstName="Jon";
  lastName="Doe";

  // not case sensative:
  firstNameSearchable=["j","o", "n","jo","on","jon"];   
  lastNameSerachable=["D","o","e","do","oe","doe"];
}
然后要搜索,我可以这样做,并期望它返回上述记录:

//pseudo-code:
SELECT person 
WHERE firstNameSearchable=="jo" AND
      lastNameSearchable=="oe"
这就是文本搜索的实现方式吗?你如何防止索引失控,尤其是当你有一段或一些东西的时候?是否有其他常用的压缩策略?我想如果我只想要一些简单的东西,这可能会起作用,但是知道我可能遇到的问题很好

更新::

好的,所以这个概念可能是合法的。这篇博文也提到了它:

注意:上面博客文章中的源代码不适用于Lucene的当前版本。我安装了旧版本(2.9.3)作为一个快速修复,因为谷歌应该尽快推出自己的文本搜索应用程序引擎

下面的响应中建议的解决方案是一个很好的快速修复方案,但由于大表的限制,只有在查询一个字段时才有效,因为在查询中只能对一个属性使用非相等运算符:

db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2", "abc", u"abc" + u"\ufffd")
db.GqlQuery(“从MyModel中选择*,其中prop>=:1和prop<:2”,“abc”,u“abc”+u”\ufffd”)
如果要查询多个属性,可以为每个属性保存索引。在我的例子中,我使用它在小文本字段上实现一些自动建议功能,而不是在文档中实际搜索单词和短语匹配(您可以使用上面的博客文章实现)。事实证明,这是非常简单的,我真的不需要一个图书馆。此外,我预计如果有人正在寻找“拉里”,他们将开始键入“LA…”,而不是开始在词的中间:“ARRY”。因此,如果属性是一个人的名字或类似的东西,索引只有以第一个字母开头的子字符串,因此“Larry”的索引将只是{“l”,“la”,“lar”,“larr”,“Larry”}

我对电话号码之类的数据做了一些不同的处理,在这些数据中,您可能希望搜索从开头或中间数字开始的号码。在本例中,我只存储了以长度为3的字符串开始的整个子字符串集,因此电话号码“123-456-7890”将是:{“123”、“234”、“345”、…“123456789”、“234567890”、“1234567890”},总共(10*((10+1)/2))-(10+9)=41个索引。。。实际上,为了删除一些不太可能被使用的子字符串,我做了一些更复杂的事情,但是你明白了

那么您的查询将是: (Pseaudo代码) 从其中的人员中选择* firstNameSearchIndex==“lar” phonenumberSearchIndex==“1234”


appengine的工作方式是,如果查询子字符串与属性中的任何子字符串匹配,则该子字符串将被视为匹配项。

实际上,这不会缩放。对于n个字符的字符串,需要n个阶乘索引项。500个字符的字符串需要1.2*10^1134个索引才能捕获所有可能的子字符串。在实体完成对数据存储的写入之前,您将因年老而死亡

像search.SearchableModel这样的实现为每个单词创建一个索引项,这更现实一些。您无法搜索任意子字符串,但有一个技巧可以让您匹配前缀:

发件人:

db.GqlQuery(“从MyModel中选择* 其中,道具>=:1和道具<:2“, “abc”,u“abc”+u“\ufffd”)

这会将每个MyModel实体与 开始的字符串属性 与abc的字符。unicode 字符串u“\ufffd”表示 最大可能的Unicode字符。 在中对特性值进行排序时 一个索引,该索引中的值 范围是所有开始的值 使用给定的前缀


发明自己的全文搜索真的比安装库简单吗?或者使用google.appengine.ext.db.searchablemodel?嗨,尼克,什么是google.appengine.ext.db.searchablemodel?我只能在网上找到转瞬即逝的参考资料。嘿,德鲁,你关于不为更大的条目缩放的论点是正确的。但我很确定缩放效果并没有你计算的那么糟糕。例如5!是5x4x4x2x1,但当我计算完后,计算似乎实际上是5+4+3+2+1(加法而不是乘法)。这个公式是n*(n+1)/2。所以一个500个字符的字符串需要少于125250个索引。。。这仍然是很多。