Google App Engine: возможно ли выполнить запрос Gql LIKE? - PullRequest
120 голосов
/ 07 сентября 2008

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

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

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

Ответы [ 12 ]

78 голосов
/ 07 сентября 2008

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

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

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

Наблюдайте за этой сессией Google IO для более подробного и подробного объяснения этого.

75 голосов
/ 08 июля 2009

Я столкнулся с той же проблемой, но нашел что-то на страницах Google App Engine:

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

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

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

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

возможно, это могло бы сработать;)

12 голосов
/ 26 января 2010

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

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

9 голосов
/ 26 ноября 2013

Вам необходимо использовать службу поиска для выполнения полнотекстовых поисковых запросов, аналогичных 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
}

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

4 голосов
/ 02 октября 2012

Движок приложения запустил универсальную службу полнотекстового поиска в версии 1.7.0, которая поддерживает хранилище данных.

Подробности в объявлении .

Больше информации о том, как использовать это: https://cloud.google.com/appengine/training/fts_intro/lesson2

3 голосов
/ 01 июня 2011

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

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

String start = "foo";
    ... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");
1 голос
/ 12 августа 2016

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

@Index
    public ArrayList<String> searchName;

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

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

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

1 голос
/ 19 марта 2015

В общем, даже если это старый пост, способ создать '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)
1 голос
/ 25 июня 2014

Я проверил это с помощью низкоуровневого API Java 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);
1 голос
/ 20 июня 2012

Просто следуйте здесь: 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(...)
...