2012-04-10 69 views
2

有沒有人使用MongoDB的數組類型來實現堆棧?使用MongoDB數組作爲堆棧

我知道我可以append到一個數組,像這樣:

db.blogposts.update({_id:5}, {$push: {comments: {by: "Abe", text:"First"}}}) 

這裏,數組的結尾是堆棧的頂部...我不明白的方式以實現此在第零指數的堆棧頂部,但我很想錯。

而且我知道我可以peek在的陣列,像這樣的最後一個值:

db.blogposts.find({_id:5}, {comments: {$slice:-1}}) 

有了這樣的一個實現,我可以「偷看」在棧中的MongoDB更新頂部聲明?這會給我語義,「如果堆棧頂部是X,則將此項目推送到堆棧上」。我需要這是一個原子操作!

任何意見讚賞。謝謝!

+0

看起來像推到一個數組的開頭尚未實現:HTTPS://jira.mongodb .org/browse/SERVER-2191?page = com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel – 2012-04-10 18:52:42

+1

重複的[你可以有mongo $ push prepend而不是append?](http://stackoverflow.com/questions/10131957/can-you-have-mongo-push-prepend-instead-append) – 2015-08-15 04:29:38

回答

4

不幸的是,目前還沒有完全按照您所描述的方式來執行此操作的方法。

正如克里斯沙恩指出,https://jira.mongodb.org/browse/SERVER-2191 - 「$推(),以陣列前面」,同樣https://jira.mongodb.org/browse/SERVER-1824 - 「爲插入到特定的數組索引支持」會有所幫助,但這些功能目前尚未提名爲具體的發佈版本。

作爲一種可能的解決方法,您可以向文檔中添加一個名爲「lastElement」(或等價物)的字段,該字段包含推送到數組的最後一個元素的副本。在你的update語句中,你可以查詢「lastElement」值,如果匹配,同時將它設置爲新值,並在同一個原子操作中將相同的值推送到數組中。

例如:

> db.blogposts.save({_id:5, comments:[{by: "Abe", text:"First"}], lastElement:{by: "Abe", text:"First"}}) 
> db.blogposts.find().pretty() 
{ 
    "_id" : 5, 
    "comments" : [ 
     { 
      "by" : "Abe", 
      "text" : "First" 
     } 
    ], 
    "lastElement" : { 
     "by" : "Abe", 
     "text" : "First" 
    } 
} 
> db.blogposts.update({"lastElement.text":"First"}, {$set:{lastElement:{by: "Joe", text:"Second"}}, $push:{comments:{by: "Joe", text:"Second"}}}) 
> db.blogposts.find().pretty() 
{ 
    "_id" : 5, 
    "comments" : [ 
     { 
      "by" : "Abe", 
      "text" : "First" 
     }, 
     { 
      "by" : "Joe", 
      "text" : "Second" 
     } 
    ], 
    "lastElement" : { 
     "by" : "Joe", 
     "text" : "Second" 
    } 
} 
> 

作爲替代方案,你可以考慮在「更新,如果目前的」中所列的「原子操作」文件的部分戰略:http://www.mongodb.org/display/DOCS/Atomic+Operations

我知道這些都是工作周圍和不理想的解決方案。希望上面的內容能幫助你實現你的目標,或者至少爲你提供一些想法讓你想出不同的解決方案。如果您這樣做,請在此分享,以便任何可能遇到類似問題的社區成員可能會從您的體驗中受益。謝謝。

+0

這幾乎是我在模式中實現的解決方案。感謝您確認我沒有遺漏任何東西。 – 2012-04-10 22:44:25

+0

@RussWeeks:現在已經實施。你能否改變接受的答案?從v2.5.3開始,你可以使用'$ push - $ each - $ position:0'語法,這很尷尬。此外,請幫助[通過在此問題上投票實施$ unshift](https://jira.mongodb.org/browse/SERVER-19974)。 – 2015-08-15 04:26:30

3

看起來如MongoDB的V2.6的,這是現在通過$position運營商支持:http://docs.mongodb.org/manual/reference/operator/update/position/

db.blogposts.update(
    {_id:5} 
    , {$push: 
     {comments: 
      {$each: {by: "Abe", text:"First"} 
      , $position:0 } 
     } 
    } 
); 
+0

'$ push - $ each - $ position:0'語法很笨拙。請幫助[通過對此問題進行投票實施$ unshift](https://jira.mongodb.org/browse/SERVER-19974)。 – 2015-08-15 04:25:38