首页 > 解决方案 > 更新 mongo/mongoose 版本后更新文档时出错

问题描述

这是一些旧代码,我正在将我的 mongo db 从 3.4 更新到 3.6,因为 db 主机正在将 dbs 迁移到 3.6,并且由于 mongoose 4.0.6 上使用的某些方法在 mongo 3.6 上已弃用,我将 mongoose 更新为 5.2.2

这段工作正常的代码停止工作(还有其他代码,但我能够找出问题所在):

exports.editProduct = function(req, res){
  Item.find().exec(function(err, itens){
    Product.find().exec(function(err, products){
      Category.find().exec(function(err, categories){
        Product.findOne({ _id: req.body.idProduct }).exec(function(err, product){
          if(err){
            return err;
          }

          _.extend(product, req.body);
          product = formatDescription(product);

          product.featured = req.body.featured === 'on'
          product.active = req.body.active === 'on'

          product.save(function(err, product){
            console.log(err)
          });

          return res.render('admin/products/edit', { title: 'Edit successfully', product: product, itens: itens, products: products, categories: categories});
        });
      });
    });
  });
};

我得到的错误是:

TypeError: _arr[i].emit is not a function
  at EventEmitter.notify (/Users/iagowp/Desktop/trampos/frutacor/node_modules/mongoose/lib/types/documentarray.js:337:19)
  at EventEmitter.emit (events.js:187:15)
  at EventEmitter.emit (domain.js:442:20)
  at model.Document.(anonymous function) [as emit] (/Users/iagowp/Desktop/trampos/frutacor/node_modules/mongoose/lib/document.js:146:42)
  at model.Model.$__handleSave (/Users/iagowp/Desktop/trampos/frutacor/node_modules/mongoose/lib/model.js:233:10)
  at model.Model.$__save (/Users/iagowp/Desktop/trampos/frutacor/node_modules/mongoose/lib/model.js:243:8)
  at /Users/iagowp/Desktop/trampos/frutacor/node_modules/kareem/index.js:278:20
  at _next (/Users/iagowp/Desktop/trampos/frutacor/node_modules/kareem/index.js:102:16)
  at process.nextTick (/Users/iagowp/Desktop/trampos/frutacor/node_modules/kareem/index.js:452:38)
  at process._tickCallback (internal/process/next_tick.js:61:11)

该文档如下所示:

{ photos:
   { photo1: '',
     photo2: '' },
  name: 'LANCHE CAIXA LIVRO',
  type: 'cesta',
  related_products:
   [ 58d953db02cbeb1000c2252c,
     59c41c8920a98825003bc01f,
     5a9704cfc85a33130048d03b ],
  addons:
   [ 58c98ff147d68f1000dc0aa4,
     58ecfc1e3d2a39002ec48c30,
     59cb9de1d554581100b6a63d ],
  featured: false,
  active: false,
  _id: 59c41f5020a98825003bc026,
  slug: 'lanche-caixa-livro',
  code: '2475',
  inventory: null,
  descricao_avulsa: '',
  price: 7900,
  discount: null,
  category: 583f0ec84feeca1000835804,
  description:
   [ { _id: 5b490101bad42c1a2c93e074,
       item: 59c4325720a98825003bc078,
       quantity: null },
     { _id: 5b490101bad42c1a2c93e075,
       item: 59c52510a9685111001c2fa1,
       quantity: 1 },
     { _id: 5b490101bad42c1a2c93e076,
       item: 5849bc4f57d6331000bd3785,
       quantity: 1 },
     { _id: 5b490101bad42c1a2c93e077,
       item: 58948881d540031000b87c05,
       quantity: 1 },
     { _id: 5b490101bad42c1a2c93e078,
       item: 589488f3d540031000b87c06,
       quantity: 1 },
     { _id: 5b490101bad42c1a2c93e079,
       item: 5849bbdc57d6331000bd3781,
       quantity: 1 },
     { _id: 5b490101bad42c1a2c93e07a,
       item: 589489b0d540031000b87c0c,
       quantity: 1 },
     { _id: 5b490101bad42c1a2c93e07b,
       item: 5849ac3657d6331000bd3773,
       quantity: 1 },
     { _id: 5b490101bad42c1a2c93e07c,
       item: 58eb8d51147a3b1a000e0d5d,
       quantity: null } ],
  __v: 18 }

我在出错前放了一个 console.log,我发现 _arr[i] 是 '59c52510a9685111001c2fa1',这是描述中的一个项目。我尝试将其转换为 ObjectId,如下所示:

product.description = product.description.map(function(product){
  product.item = mongoose.Types.ObjectId(product.item)
  return product;
});

但是什么也没发生。

编辑:哦,我的模型看起来像这样

var ProductSchema = new Schema({
  name: { type: String, default: '' },
  inventory: { type: Number },
  type: { type: String, default: 'cesta' },
  price: { type: Number, required: true },
  discount: { type: Number},
  description: [{
    item: { type : Schema.ObjectId, ref : 'Item' },
    quantity: Number
  }],
  photos: {
    photo1: String,
    photo2: String
  },
  related_products: [{ type : Schema.ObjectId, ref : 'Product' }],
  addons: [{ type : Schema.ObjectId, ref : 'Product' }],
  category: { type: Schema.ObjectId, ref: 'Category' },
  code: { type: String }, 
  descricao_avulsa: String,
  slug: String,
  featured: {type: Boolean, default: false,},
  active: {type: Boolean, default: false}
});

另外,如果我删除描述,它会起作用。当我使用相同的 formatDescription 函数创建产品时,它工作正常。

我怎样才能让它再次工作?

标签: mongodbmongoose

解决方案


好的,所以我在Github上寻求帮助,认为这可能是对 mongoose 的无证重大更改。

问题出在哪里:我的 req.body 有一个描述数组,其中包含 formatDescription 函数转换为正确格式的字符串。当我在格式化之前进行扩展时,它会产生那个奇怪的错误。修复如下所示:

exports.editProduct = function(req, res){
  Item.find().exec(function(err, itens){
    Product.find().exec(function(err, products){
      Category.find().exec(function(err, categories){
        Product.findOne({ _id: req.body.idProduct }).exec(function(err, product){
          if(err){
            // TODO: PAG 500
            return err;
          }

          product.photos.photo1 = req.files.photo1 ? req.files.photo1[0].location : product.photos.photo1;
          product.photos.photo2 = req.files.photo2 ? req.files.photo2[0].location : product.photos.photo2;

          var body = formatDescription(req.body);

          body.featured = body.featured === 'on';
          body.active = body.active === 'on';
          _.extend(product, body);

          product.save(function(err, product){
            if(err) console.log(err)
          });

          return res.render('admin/products/edit', { title: 'Edit successfully', product: product, itens: itens, products: products, categories: categories});
        });
      });
    });
  });
};

基本上我只是在将其放入 Product 对象之前格式化了我想要的方式,即 Mongoose 对象


推荐阅读