2016-03-21 80 views

回答

0

這是第一代碼我發現,實際工作:

Meteor.users.update(Meteor.userId(), {$pull: {favorites: {$in: [i]}}}) 

$in顯然確實部分匹配。這似乎從this answer比工作更安全代碼:

Meteor.users.update(
    { "_id": this.userId }, 
    { "$pull": { "favorites": { "$elemMatch": { "$eq": i } } } } 
) 
+0

爲什麼更安全?這實際上是一種寵物,因爲太多的人使用'$ in',因爲他們「認爲」**在數組匹配時必須使用**。用例實際上是相反的,您提供了可能與該屬性相匹配的「參數數組」。您是在刪除基於匹配單個條件的元素之後。我看不出爲什麼一個「數組」使這個清晰或安全。成爲代碼似乎被沒收。 –

+0

似乎這個位置可能會被考慮在內,但是我從文檔中瞭解到它的行爲與您的代碼相同。 –

+0

那麼,爲什麼要提交一個「答案」,說明你認爲它以任何方式更安全或更好?你不能說*「我一直都知道這一點」*當你的問題沒有提出這樣的陳述時。你的問題實際上表明,*「我不知道該怎麼做」*,然後有人很高興向你展示。考慮到誤導性標題和所有內容。 –

2

因爲$pull試圖從"favorites"數組中刪除匹配的元素,它不工作。你想要做的是從「陣列內部的陣列」刪除收藏夾。

爲此,您需要的位置匹配指向nth內部元件,然後非常小心$pull表達真正刪除元素:

Meteor.users.update(
    { "favorites": { "$elemMatch": { "$elemMatch": { "$eq": 5719 } } } }, 
    { "$pull": { "favorites.$": 5719 } } 
) 

「雙節」 $elemMatch$eq操作有點比{ 0: 5719 }更具表現力,因爲它並沒有被「鎖定」到第一個位置並且實際上正在查看匹配值。但是,如果必須的話,你可以這樣寫,或者如果你「真正的意思」是隻在第一個位置匹配這個值。

請注意,參數positional $中匹配返回的「索引」實際上是「外部」數組的那個。所以從

當然拉,如果只有過內一個嵌套的數組元素中,你可能也只是寫:

{ "$pull": { "favorites.0": 5719 } } 

使用直接「第一指數」的位置,因爲你知道內部數組將永遠在那裏。

在這兩種情況下,你的對象正確更新:

{ 
     "_id" : "FfEj5chmviLdqWh52", 
     "favorites" : [ 
       [ 
         "2016-03-21T17:46:01.441Z", 
         "a" 
       ] 
     ] 
} 

如果你想$pull從收藏夾整個陣列的條目,那麼$eleMatch只需要撥回一個元素:

Meteor.users.update(
    { "_id": this.userId }, 
    { "$pull": { "favorites": { "$elemMatch": { "$eq": 5719 } } } } 
) 

甚至:

Meteor.users.update(
    { "_id": this.userId }, 
    { "$pull": { "favorites": { "$elemMatch": { "0": 5719 } } } } 
) 

注意到:

{ "_id": this.userId }, 

是長形式我們一般使用的「查詢」選擇,特別是當我們需要標準的文檔_id「比其他」。儘管如此,MiniMongo聲明至少需要文檔的_id

由於$pull已經適用於數組,所以聲明的其餘部分有一個「少」$elemMatch

從外陣列刪除整個匹配元素:

{ 
     "_id" : "FfEj5chmviLdqWh52", 
     "favorites" : [] 
} 
+0

謝謝,但我想刪除具有指定ID(最喜歡的第一個元素)所有(最好的)的最愛。 –

+0

@CeesTimmerman那麼這怎麼回事呢?那怎麼不是你問的?第一個元素已被刪除。 –

+0

我正在查找的ID是收藏夾的第一個元素,應該從收藏夾數組中刪除整個收藏夾。你的短代碼並沒有刪除最喜歡的(也不是最喜歡的ID),而你的長代碼給了我這個:'MongoError:'收藏夾中的美元($)前綴字段'$ elemMatch'。$ elemMatch'無效存儲「。 –