Gaelyk tutorial为数据存储提供了一些不错的低级包装,this Gaelyk google groups article描述了一种简单的方法,通过简单地将密钥存储在实体的集合中来建模关系。
我的问题是如何对集合中的值执行查询?以下是一些示例代码,以澄清...
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'查询的功能?
答案 0 :(得分:6)
回答仅仅是为了将来登陆此页面的用户:
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的一个很棒的功能。
答案 1 :(得分:3)
执行此操作的一种方法是将作者键作为实体“Book”中的一个字段。因此,您可以先查询该书,然后获取作者。
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 :(得分:2)
顺便说一下,关于这个主题的一点点更新:你可能想看看最近发布的Gaelyk 1.0的新Query DSL功能。
http://gaelyk.appspot.com/tutorial/app-engine-shortcuts#query
这可以简化可以对数据存储区进行的大量查询。