Mongoose更新子文档的子文档

时间:2014-09-23 00:31:24

标签: javascript node.js mongodb mongoose mongodb-query

我的架构定义如下。 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调用首先通过auth中间件

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);
        }
      )
    // }
   // })
})
};

1 个答案:

答案 0 :(得分:3)

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

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,因为位置运算符只包含第一个,因此无法在“内部”数组的位置进行更新。 strong>匹配,或“外部”数组中的位置。