Gaelyk:如何对集合属性执行数据存储查询

发布于 2024-10-16 00:05:05 字数 1509 浏览 9 评论 0原文

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”查询的功能?

The Gaelyk tutorial provides some nice low level wrappers to the datastore and this Gaelyk google groups article describes an easy way to model relationships by simply storing the keys in a collection on the entity.

My question is how can I perform queries on the values within the collections? Here is some example code to clarify...

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"

How can I create a query that that searches for matches within a collection property of an Entity? ie how to recreate the functionality of the mythical 'FilterOperator.CONTAINS' query above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

驱逐舰岛风号 2024-10-23 00:05:05

回答只是为了用户将来登陆此页面:

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 的一个很棒的功能。

Answering just for the sake of users landing to this page in future:

Query.FilterOperator.EQUAL will find inside the list of keys as well (it works as CONTAINS, in case of lists). So now your second case looks like:

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"

and the assertion passes :)

This may look strange at first sight but it is indeed a great feature of DataStore.

蝶…霜飞 2024-10-23 00:05:05

执行此操作的一种方法是将作者密钥作为实体“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

One way to do this would be to have the author key as one of the fields in your entity "Book". Therefore, you can query the book first and then get the authors for it.

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
友谊不毕业 2024-10-23 00:05:05

顺便说一句,关于这个主题的一些更新:您可能想看看最近发布的 Gaelyk 1.0 的新 Query DSL 功能。

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

这应该会简化对数据存储进行的大量查询。

By the way, a little update on this topic: you might want to have a look at the new Query DSL feature of Gaelyk 1.0, which was released recently.

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

This should simplify a lot of the queries one can make against the datastore.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文