2015-02-09 115 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