【问题标题】:Gaelyk: How to perform datastore queries on collection attributesGaelyk:如何对集合属性执行数据存储查询
【发布时间】:2011-02-05 00:35:28
【问题描述】:

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

【问题讨论】:

    标签: google-app-engine groovy google-cloud-datastore gaelyk


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢,我希望可以避免必须不断跟踪并确保反向引用是同步的。 Python GAE 有ReferencePropery,它会自动保持反向链接一致。你知道是否有与 ReferenceProperty 等效的 Java/Groovy 吗?
      • @Chris:如果你真的想对关系建模,我猜你必须使用 GAE 的 JDO/JPA 实现。但是,我不建议使用它们。他们无法完全抽象出 BigTable 不是关系数据库的事实。此外,当涉及到更复杂的关系时,它们似乎是错误的/hacky。它还引入了新的 JAR 依赖项,这将增加应用程序的启动时间。 Objectify 可能是个不错的选择。
      【解决方案3】:

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

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

      这应该会简化很多可以对数据存储区进行的查询。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-02
        • 2019-04-23
        • 1970-01-01
        • 2012-02-13
        • 1970-01-01
        • 2011-03-29
        • 1970-01-01
        • 2018-11-25
        相关资源
        最近更新 更多