【问题标题】:Mongoose update subdocument of subdocument猫鼬更新子文档的子文档
【发布时间】:2017-06-28 10:28:56
【问题描述】:

我的架构定义如下。 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]
});

我想在用户模式中向卡中添加交易,但我不确定如何在 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);
        }
      )
    // }
   // })
})
};

【问题讨论】:

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


    【解决方案1】:

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

    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 尝试在“内部”数组中的位置进行更新是不可能的,因为位置运算符将只包含 first 匹配,或“外部”数组中的位置。

    【讨论】:

    • 我不确定,但我得到 RangeError: Maximum call stack size exceeded when I try the above code.
    • @gaurav 听起来你在循环中做某事。如果不发布代码,不确定您在做什么。
    • 嗨,尼尔,我没有在循环中做任何其他事情。我不得不更改您通过 ObjectId() 搜索的答案,但我仍然遇到同样的错误。如果我不执行推送操作,我不会收到错误消息。
    • @gaurav 将您尝试的代码添加到您的问题中,这样我们就可以看到您实际上做错了什么。
    • @gaurav 尝试使用.toObject() 方法来获取纯对象数据而不是猫鼬文档。不过,这确实应该被隐式调用。 _id 也是如此,它确实应该由 mongoose 从字符串自动转换,除非架构列表中没有显示覆盖的内容。我可以问一下他们为什么在他们自己的集合中创建“交易”以及嵌入它们的某种原因吗?并不是说这是无效的事情,只是不平常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 2015-06-03
    • 2017-05-07
    相关资源
    最近更新 更多