2015-02-09 55 views
0

我有一个这样的结构:UpdateOperations嵌入式阵列

{ 
    _id: 123, 
    bs: [ 
    { 
     _id: 234, 
     cs: [ 
     { 
      _id: 456, 
      ds : [ 
      { 
       _id: 678, 
       emails[ 
       "[email protected]" 
       ] 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 

我对吗啡类看起来这

@Entity 
public class A { 

    @Id 
    private ObjectId id; 

    @Embedded 
    private List<B> bs; 
} 

public class B { 

    private ObjectId id; 

    @Embedded 
    private List<C> cs; 
} 

public class C { 

    private ObjectId id; 

    @Embedded 
    private List<D> ds; 
} 

public class D { 

    private ObjectId id; 

    @Embedded 
    private List<String> emails; 
} 

我所试图做的是插入邮件内嵌入式阵列与吗啡不检索所有元素A并使用updateFirst。

这是我试图执行

Query<Event> query = this.basicDAO.createQuery(); 
query.criteria(Mapper.ID_KEY).equal(new ObjectId(aID)); 
query.criteria("bs.cs.id").equal(new ObjectId(cID)); 
query.criteria("bs.cs.ds.id").equal(dID); 

UpdateOperations<Event> updateOps = this.basicDAO.createUpdateOperations().set("bs.cs.ds.$.emails", email); 

this.basicDAO.update(query, updateOps); 

查询与说

$操作不起作用“与遍历数组嵌套查询”我也读到这篇文章Update an item in an array that is in an array

所以,我想是这样的:

D d = new D(dID); 
C c = new C(new ObjectId(cID)); 

Query<Event> query = this.basicDAO.createQuery(); 
query.criteria(Mapper.ID_KEY).equal(new ObjectId(aID)); 
query.field("bs.cs").hasThisElement(c); 
query.field("bs.cs.ds").hasThisElement(d); 

UpdateOperations<Event> updateOps = this.basicDAO.createUpdateOperations().set("bs.cs.ds.emails", email); 

this.basicDAO.update(query, updateOps); 

然而,它仍然无法正常工作。任何想法如何解决这个?我收到的错误消息是不能使用零件...横切元素

+0

我发现的其他事情,可能与我的问题有关。 Morphia不存储空的Java列表。所以当我尝试在我之前保存的空数组中插入一个元素时,对于Morphia与未存储列表相同,响应列表为空而不是空列表,因此将结果设置为空值在错误 – arthurfnsc 2015-02-09 15:47:12

+0

您可以使用位置匹配运算符'$'来匹配多层嵌套数组。这是你应该在模式中完全避免嵌套数组的原因之一。这个模式有什么用处?不同的领域意味着什么? – wdberkeley 2015-02-09 18:43:08

+0

我不能给出项目的所有细节,但让我们来做这个比喻:想象一下,我可以创建一个可以有一堆版本(B类)的事件(类A),每个版本可以有一堆主题(C类)每个主题可以有一堆讲座(D班)。在一期活动结束时,我希望人们在他们喜欢的演讲中投票。这不是我的模式,只是一个比喻。我的问题可以理解为更新一个事件版本中主题演讲的投票。这不是完美的类比,但我认为比A,B,C和D更好 – arthurfnsc 2015-02-09 23:14:59

回答

1

根据您的备用用例,我认为您应该“反转”您的模式。每个文档将代表lecture,将与被标记的themeeditionevent

{ 
    "_id" : ObjectId("54da1ff0a9ce603a239c3075"), 
    "event" : "X0004", 
    "edition" : "A0002, 
    "theme" : "RT0005", 
    "votes" : 22 
} 

eventeditiontheme可以是某种标识符,并可能引用eventeditiontheme其他集合中的文档。要投上一票为特定的演讲,只是_id更新:

db.test.update({ "_id" : ObjectId("54da1ff0a9ce603a239c3075") }, { "$inc" : { "votes" : 1 } }) 

虽然我不知道你的全部要求,我觉得这是给你的例子使用的情况下更好的基本设计。

+0

我的问题之一是事件编辑主题和讲座只是类比。在我真正的问题中,这些实体比较复杂。我需要将邮件存储到未来的查询中,而不是仅增加它的值。我的问题仍然是在Morphia的更新操作中如何跨多个数组。 Thxs无论如何 – arthurfnsc 2015-02-10 16:45:28

+0

我只能通过与你的用例不完全类比来帮助你。我的答案中的一些想法适用于比类比更复杂的情况 - 您可能必须修改操作或使事情复杂一点。但有一件事是肯定的,你会发现使用4层嵌套的阵列非常困难。 – wdberkeley 2015-02-10 16:55:10

+0

你给我一个很好的想法,以避免4深嵌套数组。我不知道那个mongo“限制”,所以我会改变我的模型。 Thx @wdberkeley – arthurfnsc 2015-02-10 18:25:07