Google App Engine: возможно ли выполнить запрос Gql LIKE?

Простой на самом деле. В SQL, если я хочу искать текстовое поле для нескольких символов, я могу сделать:

SELECT blah FROM blah WHERE blah LIKE '%text%'

Документация для App Engine не упоминает о том, как это сделать, но, безусловно, это достаточно распространенная проблема?

Ответ 1

BigTable, который является базовым компонентом для App Engine, будет масштабироваться до миллионов записей. В связи с этим App Engine не позволит вам выполнять какие-либо запросы, которые приведут к сканированию таблицы, поскольку производительность будет ужасной для хорошо заполненной таблицы.

Другими словами, каждый запрос должен использовать индекс. Вот почему вы можете выполнять запросы =, > и <. (Фактически вы также можете сделать !=, но API делает это, используя комбинацию из > и < запросов). Это также объясняет, почему среда разработки отслеживает все запросы, которые вы выполняете, и автоматически добавляет любые отсутствующие индексы к вашему index.yaml.

Невозможно индексировать запрос LIKE, чтобы он просто не был доступен.

Посмотрите этот сеанс Google IO, чтобы получить гораздо лучшее и подробное объяснение этого.

Ответ 2

У меня такая же проблема, но я нашел что-то на страницах движка Google:

Совет. Фильтры запросов не имеют явного способа сопоставления только части строкового значения, но вы можете подделывать совпадение префикса с использованием фильтров неравенства:

db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
            "abc",
            u"abc" + u"\ufffd")

Соответствует каждому объекту MyModel с атрибутом string, который начинается с символов abc. Строка unicode u "\ ufffd" представляет собой максимально возможный символ Юникода. Когда значения свойств сортируются в индексе, значения, которые попадают в этот диапазон, представляют собой все значения, начинающиеся с данного префикса.

http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html

возможно, это может сделать трюк;)

Ответ 3

Altough App Engine не поддерживает запросы LIKE, посмотрите на свойства ListProperty и StringListProperty. Когда для этих свойств выполняется тест равенства, тест будет фактически применяться ко всем членам списка, например, list_property = value проверяет, отображается ли значение в любом месте списка.

Иногда эта функция может использоваться как обходной путь к отсутствию запросов LIKE. Например, это позволяет сделать простой текстовый поиск, как описано в этом сообщении.

Ответ 4

Вам необходимо использовать службу поиска для выполнения полнотекстовых поисковых запросов, аналогичных SQL LIKE.

Gaelyk предоставляет язык, специфичный для домена, для выполнения более удобных поисковых запросов. Например, следующий фрагмент найдет первые десять книг, отсортированных по последним, с заголовком, содержащим fern и жанр точно соответствует thriller:

def documents = search.search {
    select all from books
    sort desc by published, SearchApiLimits.MINIMUM_DATE_VALUE
    where title =~ 'fern'
    and genre =  'thriller'
    limit 10
}

Как написано как оператор Groovy match =~. Он поддерживает такие функции, как distance(geopoint(lat, lon), location).

Ответ 6

Посмотрите на Objectify здесь, это похоже на API доступа к хранилищу данных. Существует FAQ с этим вопросом, конкретно, вот ответ

Как сделать подобный запрос (LIKE "foo%" )
Вы можете сделать что-то вроде startWith или endWith, если вы измените порядок при сохранении и поиске. Вы выполняете запрос диапазона с начальным значением, которое вы хотите, и значение, которое находится выше того, которое вы хотите.

String start = "foo";
    ... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");

Ответ 7

Просто следуйте за нами: init.py # 354" > http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/search/ INIT.py # 354

Это работает!

class Article(search.SearchableModel):
    text = db.TextProperty()
    ...

  article = Article(text=...)
  article.save()

To search the full text index, use the SearchableModel.all() method to get an
instance of SearchableModel.Query, which subclasses db.Query. Use its search()
method to provide a search query, in addition to any other filters or sort
orders, e.g.:

  query = article.all().search('a search query').filter(...).order(...)

Ответ 8

Я тестировал это с помощью низкоуровневого Java API GAE Datastore. Я и прекрасно работаю

    Query q = new Query(Directorio.class.getSimpleName());

    Filter filterNombreGreater = new FilterPredicate("nombre", FilterOperator.GREATER_THAN_OR_EQUAL, query);
    Filter filterNombreLess = new FilterPredicate("nombre", FilterOperator.LESS_THAN, query+"\uFFFD");
    Filter filterNombre =  CompositeFilterOperator.and(filterNombreGreater, filterNombreLess);

    q.setFilter(filter);

Ответ 9

В общем, хотя это старый пост, способ создания "LIKE" или "ILIKE" состоит в том, чтобы собрать все результаты из запроса " > =", тогда цикл приводит к python (или Java) для элементов содержащий то, что вы ищете.

Предположим, вы хотите отфильтровать пользователей с помощью q = 'luigi'

users = []
qry = self.user_model.query(ndb.OR(self.user_model.name >= q.lower(),self.user_model.email >= q.lower(),self.user_model.username >= q.lower()))

for _qry in qry:
 if q.lower() in _qry.name.lower() or q.lower() in _qry.email.lower() or q.lower() in _qry.username.lower():
      users.append(_qry)

Ответ 10

Невозможно выполнить LIKE-поиск в движке приложений хранилища данных, как бы создать Arraylist, если вы хотите найти слово в строке.

@Index
    public ArrayList<String> searchName;

а затем выполнить поиск в индексе с помощью objectify.

List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();

и это даст вам список со всеми элементами, которые содержат мир, который вы сделали в поиске

Ответ 11

Если LIKE '%text%' всегда сравнивается со словом или несколькими (думаю, перестановки), и ваши данные медленно меняются (медленно означает, что это не слишком дорого - как по цене, так и по производительности - для создания и обновления индексов) Может быть ответом на объект индекса привязки (RIE).

Да, вам нужно будет создать дополнительный объект хранилища данных и заполнить его соответствующим образом. Да, есть некоторые ограничения, которые вам придется поиграть (один из 5000 ограничивает длину свойства списка в хранилище данных GAE). Но результат поиска молниеносно.

Подробнее см. RIE с Java и Ojbectify и RIE с Python.

Ответ 12

"Like" часто используется как заменитель текстового поиска для бедных. Для текстового поиска можно использовать Whoosh-AppEngine.