2014-01-30 60 views
6

我有一個結構類似這樣

{ 
    "brand": "BMW", 
    "models": ["320","545"] 
} 

模型文件必須是唯一的,而我使用下面的查詢中添加新項目時,

db.cars.update(
    {brand:'BMW'}, 
    { 
     $addToSet: { 
      models: '750' 
     } 
    }, 
    {upsert:true} 
); 

這將使

{ 
    "brand": "BMW", 
    "models": ["320","545","750"] 
} 

問題:

我該如何限制物品'模型'可以擁有的總數?假設我只想保留最後3個增加的模型。所以,如果我插入一個新的模式「135」我最終會與

{ 
    "brand": "BMW", 
    "models": ["545","750","135"] 
} 

我看了一下$slice修改但它似乎使用$push而不是$addToSet

回答

5

,因爲這是有趣的問題時,只可用實際上是一個bug的主題已被提出一個實際的request增加。至於請求,我不會屏住呼吸,增加這種行爲。

的錯誤是,你實際上可以發出以下命令:

db.cars.update(
    {brand:'BMW'}, 
    { $addToSet: { models: { $each: ['200'], $slice: 3 } } }, 
    {upsert: true} 
) 

和addToSet只會工作而忽略了修改,或警告。但是,當然你現在有四個元素在你的數組中。

來自首席技術官的評論至少指出了一個衝突。

因此,我能想到的唯一的事情是首先在一個find中使用$elemMatch對數組中的元素進行測試,並且如果兩個文檔都存在並且$ elemMatch找不到則使用常規的$ push和slice進行更新。否則,請插入新文檔或將其保留單獨使用

db.cars.update(
    {brand:'BMW'}, 
    {$push: { models: { $each: ['750'], $slice: -3 } }} 
) 

這會在導線上產生兩個以上的操作。交替地拉下文件並操作自己的陣列,這將是一個更多的操作。無論哪種方式,你都可以放鬆上升魔法,而且必須手動完成任務。

+1

謝謝你的回答,我一直只用mongo幾天,並認爲像這樣的事情是微不足道的。從我收集的鏈接中可以看出,陣列和集合之間似乎存在特別的區別,這是我不知道的。 – lostsource

+1

您提到的[SERVER-8512:支持$ slice/sort in $ addToSet](https://jira.mongodb.org/browse/SERVER-8512)「請求」已經被關閉爲「絕對不會修復」不要屏住呼吸;-)。集合目前以數組的形式實現,但將'$ addToSet'修飾符與數組'$ slice'結構混合在一起是沒有意義的。套件應被視爲無序。 – Stennie