MongoDB - 带增量的Upsert

时间:2011-10-23 20:58:23

标签: python mongodb pymongo

我正在尝试运行以下查询:

data = {
    'user_id':1,
    'text':'Lorem ipsum',
    '$inc':{'count':1}, 
    '$set':{'updated':datetime.now()},
}
self.db.collection('collection').update({'user_id':1}, data, upsert=True)

但是两个'$'查询导致它失败。是否有可能在一个声明中这样做?

2 个答案:

答案 0 :(得分:15)

首先,当您提出这样的问题时,添加有关失败原因的信息非常有帮助(例如复制错误)。

您的查询失败,因为您将$运算符与文档覆盖混合在一起。您应该对user_id和文本字段使用$ set运算符(尽管此更新中的user_id部分与此示例无关)。

所以将其转换为pymongo查询:

db.test.update({user_id:1}, 
    {$set:{text:"Lorem ipsum", updated:new Date()}, $inc:{count:1}}, 
    true, 
    false)

我已删除更新中的user_id,因为这不是必需的。如果文档存在,则此值将为1.如果该值不存在,则upsert会将更新的查询部分复制到新文档中。

答案 1 :(得分:0)

如果您尝试执行以下操作: 如果文档不存在,请插入一个新文档。 如果存在,则只增加一个字段。 然后你可以使用 $setOnInsert 和 $inc 的组合。如果歌曲存在,则 $setOnInsert 不会做任何事情,而 $inc 会增加“listened”的值。如果歌曲不存在,那么它将创建一个包含字段“songId”和“songName”的新文档。然后 $inc 将创建该字段并将值设置为 1。

let songsSchema = new mongoose.Schema({
      songId: String,
      songName: String,
      listened: Number
    })
    
let Song = mongoose.model('Song', songsSchema);
let saveSong = (song) => {
  return Song.updateOne(
    {songId: song.songId},
    {
      $inc: {listened: 1},
      $setOnInsert: {
        songId: song.songId,
        songName: song.songName,
      }
    },
    {upsert: true}
  )
  .then((savedSong) => {
    return savedSong;
  })
  .catch((err) => {
    console.log('ERROR SAVING SONG IN DB', err);
  })