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

发布于 2025-01-07 01:53:15 字数 184 浏览 2 评论 0原文

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

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

但我不知道如何使用部分字符串来做到这一点,请帮忙。

I have a set of entries in the datastore and I would like to search/retrieve them as user types query. If I have full string it's easy:

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

but I have no idea how to do it with partial string, please help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花海 2025-01-14 01:53:15
q := datastore.NewQuery("Products").Filter("Name >", name).Limit(20)

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

示例:

'moguz'> '莫古扎尔普'

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

There is no like operation on app engine but instead you can use '<' and '>'

example:

'moguz' > 'moguzalp'

断舍离 2025-01-14 01:53:15

编辑:啊!我刚刚意识到你的问题是 Go 特定的。我下面的代码适用于 Python。抱歉。我也熟悉 Go 运行时,稍后我可以致力于将 Python 翻译成 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 实体的数量。一点数学知识就可以为您提供合理数量的可使用字符。

EDIT: GAH! I just realized that your question is Go-specific. My code below is for Python. Apologies. I'm also familiar with the Go runtime, and I can work on translating to Python to Go later on. However, if the principles described are enough to get you moving in the right direction, let me know and I wont' bother.

Such an operation is not directly supported on the AppEngine datastore, so you'll have to roll your own functionality to meet this need. Here's a quick, off-the-top-of-my-head possible solution:

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()

To use this model, you would need to call the AddMatch method every time that you add an entity that would potentially be searched on. In your example, you have a Product model and users will be searching on it's Name. In your Product class, you might have a method AddNewProduct that creates a new entity and puts it into the datastore. You would add to that method StringIndex.AddMatch(new_product_name).

Then, in your request handler that gets called from your AJAXy search box, you would use StringIndex.GetMatchesFor(name) to see all of the stored products that begin with the string in name, and you return those values as JSON or whatever.

What's happening inside the code is that the first three characters of the name are used for the key_name of an entity that contains a list of strings, all of the stored names that begin with those three characters. Using three (as opposed to some other number) is absolutely arbitrary. The correct number for your system is dependent on the amount of data that you are indexing. There is a limit to the number of strings that can be stored in a StringListProperty, but you also want to balance the number of StringIndex entities that are in your datastore. A little bit of math with give you a reasonable number of characters to work with.

桃酥萝莉 2025-01-14 01:53:15

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

请注意,每个实体的索引数不得超过 5000 个,实体总大小不得超过 1MB。

但您也可以等待 Cloud SQL全文搜索 API 可用对于 Go 运行时。

If the number of keywords is limited you could consider adding an indexed list property of partial search strings.

Note that you are limited to 5000 indexes per entity, and 1MB for the total entity size.

But you could also wait for Cloud SQL and Full Text Search API to be avaiable for the Go runtime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文