2

有没有人使用 MongoDB 的 Array 类型来实现堆栈?

我知道我可以append像这样的数组:

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

在这里,数组的末尾是堆栈的顶部......我没有看到一种方法可以在第零个索引处的堆栈顶部实现这一点,但我很想错。

而且我知道我可以peek像这样在数组的最后一个值处:

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

通过这样的实现,我可以在 MongoDB 更新语句中“窥视”堆栈的顶部吗?这会给我语义,“如果堆栈的顶部是 X,则将此项目推入堆栈”。我需要这是一个原子操作!

任何建议表示赞赏。谢谢!

4

2 回答 2

4

不幸的是,目前没有办法完全按照您所描述的那样执行此操作。

正如 Chris Shain 指出的那样,https ://jira.mongodb.org/browse/SERVER-2191 -“$push() 到数组的前面”和类似的https://jira.mongodb.org/browse/SERVER-1824 - “支持插入特定的数组索引”会有所帮助,但这些功能目前并未针对特定的发布版本。

作为一种可能的解决方法,您可以在文档中添加一个名为“lastElement”(或等效项)的字段,其中包含推送到数组的最后一个元素的副本。在您的更新语句中,您可以查询“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

我意识到这些都是变通方法,而不是理想的解决方案。希望以上内容可以帮助您实现目标,或者至少为您提供一些思考的食物,以便您提出不同的解决方案。如果您这样做,请在此处分享,以便任何可能遇到类似问题的社区成员都可以从您的体验中受益。谢谢。

于 2012-04-10T20:59:29.723 回答
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 }
      }
  }
);
于 2014-09-28T15:45:51.780 回答