Поиск записей в хранилище данных Go GAE с использованием частичной строки в качестве фильтра - PullRequest
2 голосов
/ 17 февраля 2012

У меня есть набор записей в хранилище данных, и я хотел бы искать / извлекать их как запрос типов пользователей. Если у меня есть полная строка, это легко:

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

но я не знаю, как это сделать с частичной строкой, пожалуйста, помогите.

Ответы [ 3 ]

4 голосов
/ 17 февраля 2012
q := datastore.NewQuery("Products").Filter("Name >", name).Limit(20)

Нет операции like на движке приложения, но вместо этого вы можете использовать '<' и '>'

пример:

'moguz'> 'moguzalp'

1 голос
/ 17 февраля 2012

РЕДАКТИРОВАТЬ: GAH! Я только что понял, что твой вопрос специфичен для Го. Мой код ниже для 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 или любого другого .

Что происходит внутри кода, так это то, что первые три символа имени используются для ключевого имени объекта, который содержит список строк, причем все сохраненные имена начинаются с этих трех символов. Использование трех (в отличие от некоторого другого числа) абсолютно произвольно. Правильный номер для вашей системы зависит от объема данных, которые вы индексируете. Существует ограничение на количество строк, которые могут храниться в StringListProperty, но вы также хотите сбалансировать количество сущностей StringIndex, находящихся в вашем хранилище данных. Немного математики даст вам разумное количество символов для работы.

0 голосов
/ 23 апреля 2012

Если количество ключевых слов ограничено, вы можете рассмотреть возможность добавления свойства индексированного списка частичных строк поиска.

Обратите внимание, что вы ограничены 5000 индексами на объект и 1 МБ для общего размера объекта.

Но вы также можете подождать, пока Cloud SQL и API полнотекстового поиска будут доступны для среды выполнения Go.

...