2011-03-08 58 views
31

我沿着以下的線文檔結構的東西中刪除元素:如何從雙重嵌套陣列中的MongoDB的文檔

{ 
"_id" : "777", 
"someKey" : "someValue", 
"someArray" : [ 
    { 
     "name" : "name1", 
     "someNestedArray" : [ 
      { 
       "name" : "value" 
      }, 
      { 
       "name" : "delete me" 
      } 
     ] 
    } 
    ] 
} 

我想用價值來刪除嵌套的數組元素「刪除我」。

我知道我可以使用嵌套的$ elemMatch表達式找到符合此描述的文檔。刪除相關元素的查詢語法是什麼?

回答

31

要刪除相關項目,您實際上要使用更新。更具體地說,您將使用$pull命令執行更新,該命令將從陣列中移除項目。

db.temp.update(
    { _id : "777" }, 
    {$pull : {"someArray.0.someNestedArray" : {"name":"delete me"}}} 
) 

有 「神奇」 這裏發生的一點點。使用.0表示我們知道我們正在修改someArray的第0項。使用{"name":"delete me"}表示我們知道我們計劃刪除的確切數據。

如果您將數據加載到客戶端,然後執行更新,此過程就可以正常工作。如果您想執行執行這些操作的「通用」查詢,則此過程工作得不好。

我認爲簡單地認識到更新子文檔數組通常要求您在某個時刻擁有原始內存。


針對下面的第一個評論,你也許可以幫助你的情況通過改變數據結構有點

"someObjects" : { 
    "name1": { 
     "someNestedArray" : [ 
      { 
       "name" : "value" 
      }, 
      { 
       "name" : "delete me" 
      } 
     ] 
    } 
} 

現在你可以做{$pull : { "someObjects.name1.someNestedArray" : ...

這裏是你的結構問題。 MongoDB對操作「子數組」沒有很好的支持。你的結構有一個對象數組,這些對象包含更多對象的數組。

如果你有以下的結構,你將不得不使用像$pull一個艱難的時刻:

array [ 
    { subarray : array [] }, 
    { subarray : array [] }, 
] 

如果你的結構看起來像要更新subarray你有兩個選擇:

  1. 更改您的結構,以便您可以利用$pull
  2. 請勿使用$pull。將整個對象加載到客戶端並使用findAndModify
+4

如果我們不知道的指標是什麼someArray中的項目?我應該在我原來的問題中指出這個條件,我的道歉。 – rshepherd 2011-03-11 03:50:56

+3

您指定someObjects.name1的方式似乎不起作用? – Lion789 2013-07-24 22:02:10

+2

我正在努力解決這個問題。對於查找和更新,MongoDB不支持二級深層'$'[位置操作符]。 – 2014-11-30 20:15:24

2

由於@Melkor曾評論(也許應該是一個答案,本身),

如果你不知道該指數的使用:

{_id: TheMainID, theArray._id: TheArrayID}, {$pull: {"theArray.$.theNestedArray": {_id: theNestedArrayID}}}