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)
.
Ответ 5
В App Engine запущена универсальная служба службы полнотекстового поиска в версии 1.7.0, которая поддерживает хранилище данных.
Подробности в объявлении .
Дополнительная информация о том, как это использовать: https://cloud.google.com/appengine/training/fts_intro/lesson2
Ответ 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.