如何在upsert上自动为嵌入对象生成_id?

时间:2015-05-23 09:47:55

标签: node.js mongodb mongoose

我有以下mongoose架构:

var Model = mongoose.model('Model', mongoose.Schema({
    author: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    rooms: [{
        _id: {type: mongoose.Schema.Types.ObjectId},
        title: {type: String}
    }]
}));

如果不存在,我发出以下查询来更新或创建具有默认房间的新文档:

var date = new Date(new Date().setHours(0, 0, 0, 0)).toUTCString();

this.findOneAndUpdate(author: user._id, {
     $set: {date: date},
     $setOnInsert: {rooms: [
         {title: "untitled"},
         {title: "untitled"},
       ]}
     }, {upsert: true, 'new': true});

从上面的代码中我可以看到,如果不存在新文档,我会upsert。但在mongodb中,新文档如下所示:

{
    "_id": {
        "$oid": "55604899f4e51ebf3e648f5a"
    },
    "author": {
        "$oid": "54eac9fd5fa02c1a1b1b2a3a"
    },
    "rooms": [
        {
            "title": "untitled"
        },
        {
            "title": "untitled"
        },        
    ],
    "__v": 0,
    "date": "Fri, 22 May 2015 21:00:00 GMT"
}

对于嵌套的房间对象,没有生成_id,因为我的模式描述如上。所以我的问题是如何自动为_id个对象生成rooms

1 个答案:

答案 0 :(得分:1)

要生成ID,请在更新/插入之前使用 ObjectId 类型,如下所示:

var mongoose = require('mongoose');
var ObjectId = mongoose.Types.ObjectId,
    id1 = new ObjectId,
    id2 = new ObjectId;
var date = new Date(new Date().setHours(0, 0, 0, 0)).toUTCString();

this.findOneAndUpdate(author: user._id, {
     $set: {date: date},
     $setOnInsert: {rooms: [
         {_id: id1, title: "untitled"},
         {_id: id2, title: "untitled"},
       ]}
     }, {upsert: true, 'new': true});

- 编辑 -

我最初并不理解这个问题,但我认为你所追求的是默认的id。如果是这种情况,则更改架构以包含默认值:

var generateObjectId = function() {
    var ObjectId = mongoose.Types.ObjectId,
    return new ObjectId,
}
var Model = mongoose.model('Model', mongoose.Schema({
    author: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    rooms: [
        {
            _id: {
                type: mongoose.Schema.Types.ObjectId,
                default: generateObjectId
            },
            title: {type: String}
        }
    ]
}));