使用另一个字段更新Mongodb数组

3
我有一个包含f1,f2和f3三个字段的数据库, 其中f3是一个数组。我想执行更新操作如下所示:
db.collection.update({f1:1},{$push:{f3:{$each:[f2的值],$slice:-2}}})
我在互联网上搜索了一下,但没有找到任何信息。我不确定这是否可能。非常感谢您的帮助。
示例:这是我的文档集合:
doc1 = { name: "User1", score: "Good",  History of scores: ["Good", "Bad", "Average", "Bad"] }
doc2 = { name: "User2", score: "Bad",  History of scores: ["Good", "Average", "Average", "Bad"] }
doc3 = { name: "User3", score: "Good",  History of scores: ["Good", "Good", "Average", "Good"] }

现在假设我们需要插入相应的数据:

{name : "User1", score: "Good"}

我希望文档更新user1的得分历史记录,使doc1变成如下格式:
doc1 = { name: "User1", score: "Good", History of scores: ["Bad", "Average", "Bad", "Good"] }

同样的更新应该将文档1 更改为:

doc1 = { name: "User1", score: "Good", History of scores: ["Average", "Bad", "Good", "Good"] }

我希望现在我的问题更加清晰明了。谢谢。

1
如果您能添加一些示例,那就太好了。 - Artem Mezhenin
@artech 谢谢。我已经添加了一个例子。 - Sai
2个回答

2

试试这个:

> db.c.find()
{ "_id" : ObjectId("51c156d25a334e9347b576a7"), "name" : "User1", "score" : "Good", "scores" : [ "Good", "Bad", "Average", "Bad" ] }
> db.c.update({}, {$push: {scores:{$each:['111', '222'], '$slice': -4}}})
> db.c.find()
{ "_id" : ObjectId("51c156d25a334e9347b576a7"), "name" : "User1", "score" : "Good", "scores" : [ "Average", "Bad", "111", "222" ] }

顺便提一下,这种更新方式存在一个问题:如果新对象的大小比之前的大,则会导致将该对象移动到磁盘上的另一个位置(例如,你推入了“平均”并弹出了“差”)。在原地进行更新更快,可以在第一次插入时预分配对象的空间,像这样:

> db.c.insert({ "_id" : ObjectId("51c156d25a334e9347b576a7"), "name" : "<big_tmp_string>", "score" : "<big_tmp_string>", "scores" : [ "<big_tmp_string>", "<big_tmp_string>", "<big_tmp_string>", "<big_tmp_string>" ] })
> db.c.update({ "_id" : ObjectId("51c156d25a334e9347b576a7")}, {<your_real_obj>}

@arrtech 谢谢。然而在这个例子中,值“111”和“222”是由用户每次请求查询时手动输入的,因此是已知并手动插入的。我希望实现的功能是从另一个字段(比如“score”)中获取包含的值“111”和“222”,这样就不需要手动将这些值插入到查询中。关于新对象大小的提示非常有用,是个新鲜事物。谢谢。 - Sai

1
自 MongoDB 4.2 开始,更新命令可以包含管道操作符,这使得像 this 这样的操作成为可能。
db.collection.updateOne({ f1: 1 }, [{
  $set: {
    historyOfScores: {
      $concatArrays: [
        "$historyOfScores",
        ["$score"]
      ]
    }
  }
}, {
  $set: {
    score: 'Good'
  }
}]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接