使用部分字符串作为过滤器在Go GAE数据存储区中搜索条目

时间:2012-02-17 09:01:30

标签: google-app-engine google-cloud-datastore go

我在数据存储区中有一组条目,我想搜索/检索它们作为用户类型查询。如果我有完整的字符串,那很简单:

q := datastore.NewQuery("Products").Filter("Name =", name).Limit(20)

但我不知道怎么用部分字符串来做,请帮忙。

3 个答案:

答案 0 :(得分:4)

q := datastore.NewQuery("Products").Filter("Name >", name).Limit(20)

应用引擎上没有like操作,但您可以使用'<'和'>'

示例:

'moguz'> 'moguzalp'

答案 1 :(得分:1)

编辑:GAH!我刚刚意识到你的问题是Go特定的。我的代码是针对Python的。道歉。我也熟悉Go运行时,我可以在以后转换到Python to Go。但是,如果所描述的原则足以让您朝着正确的方向前进,请告诉我,我不会打扰。

AppEngine数据存储区不直接支持此类操作,因此您必须使用自己的功能来满足此需求。这是一个快速,不可替代的解决方案:

class StringIndex(db.Model):
    matches = db.StringListProperty()

    @classmathod
    def GetMatchesFor(cls, query):
        found_index = cls.get_by_key_name(query[:3])
        if found_index is not None:
            if query in found_index.matches:
                # Since we only query on the first the characters,
                # we have to roll through the result set to find all
                # of the strings that matach query. We keep the
                # list sorted, so this is not hard.
                all_matches = []
                looking_at = found_index.matches.index(query)
                matches_len = len(foundIndex.matches)

                while start_at < matches_len and found_index.matches[looking_at].startswith(query):
                    all_matches.append(found_index.matches[looking_at])
                    looking_at += 1

                return all_matches

        return None

    @classmethod
    def AddMatch(cls, match) {
        # We index off of the first 3 characters only
        index_key = match[:3]

        index = cls.get_or_insert(index_key, list(match))
        if match not in index.matches:
            # The index entity was not newly created, so
            # we will have to add the match and save the entity.
            index.matches.append(match).sort()
            index.put()

要使用此模型,每次添加可能被搜索的实体时,都需要调用AddMatch方法。在您的示例中,您有一个Product模型,用户将在其Name上搜索。在Product类中,您可能有一个方法AddNewProduct,可以创建一个新实体并将其放入数据存储区。您将添加到该方法StringIndex.AddMatch(new_product_name)

然后,在您的AJAXy搜索框中调用的请求处理程序中,您将使用StringIndex.GetMatchesFor(name)查看以name中的字符串开头的所有存储产品,并返回这些值作为JSON或其他什么。

代码中发生的事情是名称的前三个字符用于包含字符串列表的实体的key_name,所有存储的名称都以这三个字符开头。使用三个(而不是其他一些数字)绝对是任意的。系统的正确编号取决于要编制索引的数据量。可以存储在StringListProperty中的字符串数量有限制,但您还需要平衡数据存储区中的StringIndex实体数量。一点点数学运算可以为您提供合理数量的字符。

答案 2 :(得分:0)

如果关键字数量有限,您可以考虑添加部分搜索字符串的索引列表属性。

请注意,每个实体限制为5000个索引,实体总大小限制为1MB。

但您也可以等待Cloud SQLFull Text Search API可用于Go运行时。