【问题标题】:On GoogleEngine (Java), in JDO, how do I query a list of child objects based on the id of the parent?在 GoogleEngine (Java) 上,在 JDO 中,如何根据父对象的 id 查询子对象列表?
【发布时间】:2011-07-04 13:01:21
【问题描述】:

我有两个值对象,日历和事件,它们是持久的。日历具有包含在事件列表中的属性,具有一对多的关系。 Calendar 是 Events 的父级,如下所示。

@Persistent
@Element(dependent = "true")
private List<Event> events;

现在,我希望能够根据日历对象键通过 JDO 查询检索与日历对应的事件。我对这两个类都使用了 encodedKey。

我想在 Event 实体上运行查询,而不仅仅是检索整个 Calendar 对象,因为我希望能够仅检索一组事件,用于分页。

我尝试以任何可能的方式执行此操作,但无法弄清楚如何通过父键查询。

任何帮助将不胜感激。

【问题讨论】:

    标签: java google-app-engine parent-child jdo


    【解决方案1】:

    几点说明:

    实体中的列表属性(如您的List&lt;Event&gt; events)存储为序列化的ProtocolBuffer。问题是:

    1. 如果此属性已编入索引,则限制为 5000 个元素。

    2. 每次查询列表时,都需要反序列化整个列表。如果您可以选择性地检索列表元素,这就是问题的答案:您不能。

    3. 如果实体中有多个索引列表属性,那么这可能导致Exploding Indexes

    如果您想了解 GAE 数据存储的内部结构,那么这个视频是必须的:http://www.youtube.com/watch?v=AgaL6NGpkB8

    解决方案:

    1. 使用 Slatkin 视频中的解决方案:将日历设为 Event 的父级(在数据存储方面)。然后添加一个父条件进行查询:Query.setAncestor(Key calendarKey)

      更新:应该使用实体父关系来创建“实体组”,例如交易范围的单位。

    2. 反转情况:创建具有指向事件所属日历的日历属性的事件实体。然后,您可以简单地查询具有 'calendar == calendarKey` 的事件。

    【讨论】:

    • Peter,您的解决方案是使用普通数据存储 API 查询,而不是 JDO。我实际上找到了方法。 JDO 支持对子对象的属性(如 parentKey)进行注释。这由 JDO 自动处理,无需编程。见下文:@Persistent @Extension(vendorName="datanucleus", key="gae.parent-pk", value="true") private String parentKey;
    • 关于 5000 的上限,究竟是什么意思?这是否意味着父类的一个实例最多只能有 5000 个事件的事件列表。谢谢?
    • 准确地说:每个实体限制为 5000 个索引条目。每个列表属性元素都会产生一个索引条目(如果已编入索引)。
    • 我不是 JDO 的粉丝,因为它试图欺骗开发人员 Datastore 是一个 SQL 数据库。在我们的项目中,我们使用 Objectify:code.google.com/p/objectify-appengine
    • @oviroa @Peter 的建议仍然有效:不是让Calendar 拥有Event 实体列表,而是让每个Event 引用日历。请注意,这是 instead,而不是除了。此外,没有理由将密钥存储为字符串 - 直接将其存储为密钥,数据存储支持它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多