我希望为 App Engine 实现一个简单但有效的文本搜索,直到应用引擎的官方文本搜索功能发布之前我都可以使用它。我看到那里有图书馆,但安装新东西总是很麻烦。我想知道这是否是一个有效的策略:
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"
这是文本搜索的实现方式吗?你如何防止索引失控,特别是如果你有一个段落或什么的?是否有其他一些通常使用的压缩策略?我想如果我只是想要一些简单的东西,这可能会奏效,但很高兴知道我可能遇到的问题。
更新:::
好的,所以事实证明这个概念可能是合法的。这篇博文也引用了它:http: //googleappengine.blogspot.com/2010/04/making-your-app-searchable-using-self.html
注意:上面博文中的源代码不适用于当前版本的 Lucene。我安装了旧版本(2.9.3)作为快速修复,因为谷歌应该很快就会推出他们自己的应用引擎文本搜索。
下面的响应中建议的解决方案是一个很好的快速修复,但由于大表的限制,仅当您查询一个字段时才有效,因为您只能在查询中的一个属性上使用不等式运算符:
db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2", "abc", u"abc" + u"\ufffd")
如果要查询多个属性,可以为每个属性保存索引。就我而言,我将它用于小文本字段的一些自动建议功能,而不是实际搜索文档中的单词和短语匹配(您可以使用上面的博客文章实现)。事实证明这很简单,我真的不需要图书馆。另外,我预计如果有人在搜索“Larry”,他们会从输入“La...”开始,而不是从单词中间开始:“arry”。所以如果属性是一个人的名字或类似的东西,索引只有以第一个字母开头的子字符串,所以“Larry”的索引只是{“l”,“la”,“lar”,“larr ", "拉里"}
我对电话号码等数据做了一些不同的事情,您可能希望从开头或中间数字开始搜索一个。在这种情况下,我只是存储了以长度为 3 的字符串开头的整个子字符串集,因此电话号码“123-456-7890”将是:{“123”、“234”、“345”、...。 . "123456789", "234567890", "1234567890"}, 一共 (10*((10+1)/2))-(10+9) = 41 个索引...其实我做的多一点复杂的,以便删除一些不太可能使用的子字符串,但你明白了。
那么您的查询将是:(伪代码)SELECT * from Person WHERE firstNameSearchIndex == "lar" phonenumberSearchIndex == "1234"
应用引擎的工作方式是,如果查询子字符串与属性中的任何子字符串匹配,则将其计为匹配。