2012-05-22 126 views
7

的最後一個元素我有一個對象的結構是這樣的: 修改數組

{ 
    name: "...", 
    pockets: [ 
     { 
      cdate: "....", 
      items: [...] 
     } 
     ... 
    ] 
} 

在更新操作,我想一些記錄添加到項目最後口袋項目領域。使用點符號是我知道訪問子文檔的唯一方式,但我無法得到我想要的。所以,我在找的東西像這樣:

  • pockets.-1.items
  • pockets.$last.items

是否有可能修改的最後一個元素?如果是,如何?

+0

我正確的說,你想修改'items',而不是抓取它嗎? – paulmelnikow

+0

是的,你是對的。在提取時,我可以使用$ slice操作符。 – Muatik

+0

我很確定這不能用簡單的更新來完成,除非你有其他方法來匹配最後一個口袋。 – paulmelnikow

回答

2

我不知道如何使用單行查詢來完成此操作。但是你可以選擇記錄,更新並保存。

var query = <insert query here>; 
var mydocs = db.mycollection.find(query); 
for (var i=0 ; i<mydocs.length ; i++) { 
    mydocs[i].pockets[pockets.length-1].items.push('new item'); 
    db.mycollection.save(mydoc); 
} 
+3

這可能不是線程安全的,因爲另一個進程可能在查找之後和保存之前修改了數組。 –

+0

@AsyaKamsky優點...我會更新我的答案。 – McGarnagle

2

我不相信它是可以做到的自動。有一個request這個功能被添加到MongoDB。

如果您可以確保您的代碼中的線程安全,則可以使用從口袋數組(從口袋中刪除最後一個元素)的$ pop序列到變量p,然後將$ addToSet添加到p.items ,現在你可以將p推回到口袋裏。但是,如果您的應用程序無法確保只有一個進程可能同時執行此操作,則另一個進程可能會在這些步驟中修改該陣列,最終可能會丟失該更新。

您也可以查看「更新如果當前」的語義here以查看您可以通過多線程問題解決可能的競爭的另一種方式。