Mongoose / MongoDB - 更新子文档不起作用

时间:2014-06-26 02:04:18

标签: javascript arrays node.js mongodb mongoose

我找到了这样的子文档:

var incidentId = "someID1"
var alerteeId  = "someID2"

Incident.findOneQ({ _id: someID1, 'alertees._id': someID2 }, {'alertees.$': 1})
.then(function(incident) {
  var alertee = incident.alertees[0];
  alertee.responded_at = Date.now()
  return alertee.parent().saveQ().then(function(alertee) {
    console.log(alertee)
  })
})

它正确找到了alertee。但是当我更新时,它无法保存提醒者。

只有当数组中alertee的位置不是第一个时,才会出现这种情况。可以找到并更新警报器阵列中的第一个Alertee。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

这里的语法不是严格的#34; mongoose语法,所以不确定你是否在此基础上实现了一些其他层。

但实际上你想要的是{mongoose文档中指定的.findOneAndUpdate()。基本上,这将在一次通话中完成您的整个更新,您可以这样称呼它:

Incident.findOneAndUpdate(
    { "_id": someID1, "alertees._id": someID2 },
    { "alertees.$.responded_at": Date.now() },
    function(err,incident) {
        if (err) throw err;    // or do something like return the error

        if ( incident != null ) {
            incident.altertees.some(function(alertee) {
                if ( alertee._id.toString() == someID2.toString() ) {
                    console.log( alertee );
                    return 1;
                }
            });
        } else {
            console.log( "not found" );
        }
    }
);

这是最有效的更新表单,它也会返回更改的文档。在回复回调中,我使用Array#some来匹配" alertee"已更新并按原样返回。

当然,它不会调用您的"架构"上定义的任何方法或挂钩,但是只是为了更新日期,您不太可能需要它。如果你这样做,你可以像使用.findOne().save()一样使用,但是在更新数据元素之前就像我更新一样。


或者作为一个更完整的例子:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    ObjectId = require('mongodb').ObjectID;

mongoose.connect('mongodb://localhost/test');

var alerteeSchema = new Schema({
    "responded_at": Date
});

var incidentSchema = Schema({
    alertees: [alerteeSchema]
});

var Incident = mongoose.model( "Incident", incidentSchema );

var incident = new Incident();

var date1 = new Date();
var date2 = new Date(
    date1.valueOf() - ( date1.valueOf() % 1000 * 60 * 60 * 24 )
);

incident.alertees.push({ "responded_at": date1 });
incident.alertees.push({ "responded_at": date2 });

incident.save(function(err,incident) {

    if (err) throw err;
    var someID1 = incident._id;
    var someID2 = incident.alertees[1]._id;
    //var someID2 = new ObjectId();

    console.log( "before: \n" + incident );


    Incident.findOneAndUpdate(
        { "_id": someID1, "alertees._id": someID2 },
        { "alertees.$.responded_at": Date.now() },
        function(err,incident) {
            if (err) throw err;

            if (incident != null) {
                incident.alertees.some(function(alertee) {
                    console.log( "test: " + alertee );
                    if ( alertee._id.toString() == someID2.toString() ) {
                        console.log( "after: \n" + alertee );
                        return 1;
                    }
                });
            } else {
                console.log( "not found" );
            }
        }
    );

});

有了这些结果:

before:
{ __v: 0,
  _id: 53aba6c73b8d05ef77c2703b,
  alertees:
   [ { responded_at: Thu Jun 26 2014 14:51:19 GMT+1000 (EST),
       _id: 53aba6c73b8d05ef77c2703c },
     { responded_at: Thu Jun 26 2014 08:58:31 GMT+1000 (EST),
       _id: 53aba6c73b8d05ef77c2703d } ] }
test: { responded_at: Thu Jun 26 2014 14:51:19 GMT+1000 (EST),
  _id: 53aba6c73b8d05ef77c2703c }
test: { responded_at: Thu Jun 26 2014 14:51:19 GMT+1000 (EST),
  _id: 53aba6c73b8d05ef77c2703d }
after:
{ responded_at: Thu Jun 26 2014 14:51:19 GMT+1000 (EST),
  _id: 53aba6c73b8d05ef77c2703d }