Mongoose更新子文档的子文档

Mongoose update subdocument of subdocument

本文关键字:文档 更新 Mongoose      更新时间:2023-09-26

我的模式定义如下。UserSchema嵌入了卡,而卡又有许多交易。。

var TransactionSchema = new Schema({
  merchantName: String,
  transactionTime: Date,
  latitude: Number,
  longitude: Number,
  amount: Number
});
var CardSchema = new Schema({
  cardIssuer: String,
  lastFour: String,
  expirationDate: String,
  transactions : [TransactionSchema]
});
/*
 * ...User Schema... 
 */
var UserSchema = new Schema({
  name: String,
  email: { type: String, lowercase: true },
  role: {
    type: String,
    default: 'user'
  },
  hashedPassword: String,
  provider: String,
  salt: String,
  imageURL: String,
  phoneNumber: String,
  card: [CardSchema]
});

我想在userschema中添加一个交易到已经存在的卡中,但我不确定如何在mongoose/mongodb 中做到这一点

我按如下方式识别用户和卡。。

api调用首先通过身份验证中间件

function isAuthenticated() {
  return compose()
    // Validate jwt
    .use(function(req, res, next) {
      // allow access_token to be passed through query parameter as well
      if(req.query && req.query.hasOwnProperty('access_token')) {
        req.headers.authorization = 'Bearer ' + req.query.access_token;
      }
      validateJwt(req, res, next);
    })
    // Attach user to request
    .use(function(req, res, next) {
      User.findById(req.user._id, function (err, user) {
        if (err) return next(err);
        if (!user) return res.send(401);
        req.user = user;
        next();
      });
    });
}

// This is update based on Neil's answer below...
exports.create = function(req, res) {
  //var userItem = req.user;
  //console.log(userItem._id);
  //console.log(req.params.card);
  Transaction.create(req.body, function(err, transaction){
     console.log(transaction);
          //id = mongoose.Types.ObjectId;
          User.findOneAndUpdate({"card._id":id(req.params.card)},{ 
            // $set : {
            //   role: 'user1'
            // } ---- this update operation works!!
              "$push": {
                  "card.$.transactions": transaction
              } // -- this update operation causes error ...
          }, function(err,user) {
            // updated document here
            console.log('err' + err + " user " + user) ;
            return res.json(200, user);
        }
      )
    // }
   // })
})
};

向内部数组添加新元素并不困难,因为您真正需要做的就是匹配要在查询中更新的外部数组的位置,然后在更新部分应用位置$运算符。

var transaction; // and initialize as a new transaction
User.findOneAndUpdate(
    { "card._id": cardId },
    { 
        "$push": {
            "card.$.transactions": transaction.toObject()
        }
    },
    function(err,user) {
        // updated document here
    }
)

因此,对于$push操作来说,这很简单。但是,请注意,您只想$push$pull,因为尝试在"内部"数组中的位置更新是不可能的,因为位置运算符将只包含第一个匹配项或"外部"阵列中的位置。