【问题标题】:Mongoose/MongoDB update is not workingMongoose/MongoDB 更新不起作用
【发布时间】:2020-04-22 19:29:16
【问题描述】:

我知道这个问题在这里已经被打死了,但是我已经尝试了所有方法并且无法解决这个问题。快把我逼疯了。

我有一个看起来像这样的模型:

customer {
 email: String,
 password: String,
 addresses: [addresses_schema]
}

address_schema 看起来像

address {
 addr1: String,
 ... Other address fields
 primary_address: Boolean
}

现在,我想更新用户的特定地址记录,使其 primary_address 为 true。

所以我这样做:

var modifyUser = function(address_id){
  User.findOne( { email: email } ).then(function(user){
    user.update({ 'addresses._id': address_id }, 
                { $set: { 'addresses.$.primary_address': 'true' } } )

       .then(function(){
         console.log('Should eventually reach here');
        }).catch (err) {
           console.log('err:', err.message);
         });


    user.save();
  });
}

但是,如果我在更新前后获取 user.addresses,则根本没有任何变化。相反,它给了我错误:

cannot use the part (addresses of addresses._id) to traverse the element ({addresses[ {addr1: '123 test street', addr2: '', city: 'test city' ... ]}

有人可以帮助我吗?我真的很感激。谢谢!

【问题讨论】:

  • 我在这里看不到任何回调。你想直接从函数调用中返回这个吗?
  • @BlakesSeven 下面有大约 300 行代码,我不想在这里复制粘贴。我不想退回它,我只想更新我找到的用户。我已经更新了我的问题。
  • 显示处理.update() 然后查看数据的“最小示例”。无论如何,您可能真的想要.findOneAnUpdate()。但我的主要观点是这里的.update() 没有承诺或回调,所以至少在你查看数据时它可能还没有“触发”。您需要显示的不仅仅是“在此之后的更多代码”。展示真正发生的事情(简而言之),但主要行动。
  • @BlakesSeven,实际上,更新是代码的核心。将 then 调用附加到更新会提供更多信息。在我深入研究之后,我会在几分钟内再次更新。
  • “最小大小写”。应该花你 2 分钟的时间来写。创建文档,找到它,更新它,读回来。但是您在此处的代码甚至根本没有显示更新正在执行。这就是我要求你补充的。 user.update() 什么都不做。它需要被执行。它也应该是User.update(),并且可能整个事情应该是.findOneAnUpdate(),如前所述。如果你有 300 行代码操作然后调用 .save() 那么那是

标签: node.js mongodb mongoose mongodb-query


【解决方案1】:

我的钱是你正在查找的“address_id”值实际上与任何内容都不匹配。在检索到的文档上执行.update() 通常不是您想要的,这会混淆代码中的问题。

相反,最初执行.findOneAndUpdate() 以通过匹配的“电子邮件”和“addresses._id”值检索,就像在这个完整示例中所做的那样:

const mongoose = require('mongoose')
const Schema = mongoose.Schema;

var addressSchema = new Schema({
  name: String,
  primary: { type: Boolean, default: false }
});
var userSchema = new Schema({
  email: String,
  addresses: [addressSchema]
});
var User = mongoose.model('User',userSchema);

mongoose.connect('mongodb://localhost/utest');
mongoose.set("debug",true);

await User.remove();

let user = await User.create({
  email: "example@example.com",
  addresses: [
    { "name": "One" },
    { "name": "Two" }
  ]
});
console.log("1️⃣", user);

user = User.findOneAndUpdate(
  {
    "email": user.email,
    "addresses._id": user.addresses[1]._id
  },
  {
    "$set": { "addresses.$.primary": true }
  },
  { "new": true }
)
console.log("2️⃣", user);

mongoose.disconnect();

这将始终如一地产生如下输出:

1️⃣ { __v: 0,
  email: 'example@example.com',
  _id: 55ecf31a53558e183d208aa2,
  addresses:
   [ { name: 'One', _id: 55ecf31a53558e183d208aa4, primary: false },
     { name: 'Two', _id: 55ecf31a53558e183d208aa3, primary: false } ] }
2️⃣ { _id: 55ecf31a53558e183d208aa2,
  email: 'example@example.com',
  __v: 0,
  addresses:
   [ { name: 'One', _id: 55ecf31a53558e183d208aa4, primary: false },
     { name: 'Two', _id: 55ecf31a53558e183d208aa3, primary: true } ] }

并且有这样的调试输出:

Mongoose: users.remove({}) {}
Mongoose: users.insert({ email: 'example@example.com', _id: ObjectId("55ecf35627cddb243d3d8e22"), addresses: [ { name: 'One', _id: ObjectId("55ecf35627cddb243d3d8e24"), primary: false }, { name: 'Two', _id: ObjectId("55ecf35627cddb243d3d8e23"), primary: false } ], __v: 0 })
Mongoose: users.findAndModify({ 'addresses._id': ObjectId("55ecf35627cddb243d3d8e23"), email: 'example@example.com' }) [] { '$set': { 'addresses.$.primary': true } } { new: true, upsert: false, remove: false }

这只是设置示例,但主要的事情发生在 .findOneAndUpdate() 中,在 Promise 的解析中,您会看到返回的文档在指定数组元素处从原始表单“更新”。

这就是您基本上应该在这里做的事情,对返回的文档的任何进一步修改都是在完成初始“更新和获取”之后“完成”。

【讨论】:

    【解决方案2】:

    我不知道您是否真的必须使用 Mongoose,不知道这是否是您问题的要求。

    这里是直接使用 Monogodb 驱动的例子:

    var MongoClient = require('mongodb').MongoClient
      , format = require('util').format;
    
    MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
    if(err) throw err;
    
    db.collection('test').findAndModify(
      {hello: 'world'}, // query
      [['_id','asc']],  // sort order
      {$set: {hi: 'there'}}, // replacement,     replaces only the field "hi"
      {}, // options
      function(err, object) {
          if (err){
              console.warn(err.message);  //     returns error if no matching object found
          }else{
              console.dir(object);
          }
      });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-24
      • 2016-09-28
      • 1970-01-01
      • 2015-10-04
      • 1970-01-01
      • 2014-08-24
      • 2018-08-15
      相关资源
      最近更新 更多