Gaelyk: Как выполнить запросы хранилища данных к атрибутам коллекции - PullRequest
5 голосов
/ 05 февраля 2011

Учебное пособие Gaelyk предоставляет несколько хороших низкоуровневых оболочек для хранилища данных, а эта статья о группах Gaelyk google описывает простой способ моделирования отношений путем простого хранения ключей в коллекции на юридическое лицо.

Мой вопрос: как я могу выполнить запросы к значениям в коллекциях? Вот пример кода для пояснения ...

def b1 = new Entity("Book")
b1.title = "Book1"
b1.save()

def b2 = new Entity("Book")
b2.title = "Book2"
b2.save()

def author1 = new Entity("Author")  
author1.books = [b1.key, b2.key]
author1.name = "Chris"
author1.save()

// It is easy to simply query the Author entity for a standard string property
def query = new Query("Author")
query.addFilter("name", Query.FilterOperator.EQUAL, "Chris")
PreparedQuery preparedQuery = datastore.prepare(query)
def authors = preparedQuery.asList(withLimit(1))
assert authors[0].name == "Chris"

// But I can't find out how to query a collection property eg books on the Author entity
def query2 = new Query("Author")
// I would like to do something to return the entity if the value is in the collection property
// eg if there could be something like 'CONTAINS' criteria ...
// Unfortunately Query.FilterOperator.CONTAINS doesn't exist...
query2.addFilter("books", Query.FilterOperator.CONTAINS, b2.key)
PreparedQuery preparedQuery2 = datastore.prepare(query2)
def authors2 = preparedQuery2.asList(withLimit(1))
assert authors2[0].name == "Chris"

Как мне создать запрос, который ищет совпадения в свойстве коллекции сущности? то есть как воссоздать функциональность мифического запроса 'FilterOperator.CONTAINS' выше?

Ответы [ 3 ]

6 голосов
/ 02 августа 2011

Ответ только ради пользователей, заходящих на эту страницу в будущем:

Query.FilterOperator.EQUAL также найдет внутри списка ключей (в случае списков работает как CONTAINS).Итак, теперь ваш второй случай выглядит так:

def query2 = new Query("Author")
query2.addFilter("books", Query.FilterOperator.EQUAL, b2.key)
PreparedQuery preparedQuery2 = datastore.prepare(query2)
def authors2 = preparedQuery2.asList(withLimit(1))
assert authors2[0].name == "Chris"

и утверждение проходит:)

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

3 голосов
/ 05 февраля 2011

Один из способов сделать это - использовать ключ автора в качестве одного из полей в вашей сущности «Книга». Поэтому вы можете сначала запросить книгу, а затем получить авторов для нее.

def author1 = new Entity("Author")  
author1.name = "Chris"
author1.save()

def b1 = new Entity("Book")
b1.title = "Book1"
b1.authors = [author1.key]
b1.save()

author1.books = [ b1.key ]
author1.save()

def book = datastore.get(b1.key)    
def chrisAuthors = book.authors.findAll { authorKey -> datastore.get(authorKey).name == 'Chris' }
assert chrisAuthors.size() == 1
2 голосов
/ 31 августа 2011

Кстати, небольшое обновление по этой теме: возможно, вы захотите взглянуть на новую функцию Query DSL в Gaelyk 1.0, которая была недавно выпущена.

http://gaelyk.appspot.com/tutorial/app-engine-shortcuts#query

Это должно упростить множество запросов к хранилищу данных.

...