2017-09-09 30 views
0

我想使用Mongoose中的更新方法來更新我的MongoDB數據庫。我有以下模式:Mongoose嚴格的規則將不會接受Schema

let DataSchema = new mongoose.Schema({ 
    _id: Number, 
    data_hourly: [{ 
    id: Number 
    }] 

現在我想用更新我的DB:如果

let queryOptions = { 
    upsert: true, 
    setDefaultsOnInsert: true, 
    strict: true 
} 
let queryFields = { 
    $addToSet : { 
    data_hourly : { 
     id: 12345 
    } 
    } 
} 
Data.update({ _id: my._id}, 
    queryFields, queryOptions, 
    err => { 
    if (err) throw err 
}) 

這僅適用於我設置strictfalse。否則,它會拋出錯誤:

MongoError: '$addToSet' is empty. You must specify a field like so: {$addToSet: {<field>: ...}} 

我理解錯誤是因爲貓鼬忽略不嚴格,如果設置爲true,匹配模式中的任何額外字段。但是在這種情況下,我的模式是正確的,而且這些字段已經到位。那爲什麼它忽略了這個?

+0

'timestamp'實際上是什麼。猜測,你可能正在嘗試添加一個數組,或者它至少是某種對象,當它應該只是一個單一的值。 –

+0

timestamp只是一個生成的int 12345 – Chris

+0

由什麼產生?顯示代碼。它被刪除的原因是因爲它與模式所需的類型不匹配。這就是我告訴你的。如果你不能自己解決這個問題,我們需要看看輸入來自哪裏的代碼。 –

回答

1

您似乎在這裏缺少模式設計中的一些概念。獲得這樣的響應的唯一方法是由於數據與模式不匹配。在任何情況下,您基本上都不需要應用strict: false,除非您有意故意使用您認爲與模式不匹配的項目工作,或者您根本不想定義模式。通常情況下,飼料具有許多不同的屬性。

因此,對於「空」消息,要麼數據不匹配,要麼實際上已分配給正在使用的模型的模式不是您認爲的那樣。

要明確這一點的唯一真正方法是示範。以下是如何做你正在嘗試做的,處理得當:

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

mongoose.Promise = global.Promise; 
mongoose.set('debug',true); 

const uri = 'mongodb://localhost/test', 
     options = { useMongoClient: true }; 

const hourlySchema = new Schema({ 
    id: Number 
},{ _id: false }); 

const dataSchema = new Schema({ 
    _id: Number, 
    data_hourly: [hourlySchema] 
},{ _id: false }); 

const Data = mongoose.model('Data', dataSchema); 

function log(data) { 
    console.log(JSON.stringify(data,undefined,2)) 
} 

(async function() { 

    try { 

    const conn = await mongoose.connect(uri,options); 

    await Promise.all(
     Object.keys(conn.models).map(m => conn.models[m].remove()) 
    ); 


    let data = [ 
     { _id: 12345, data_hourly: 12345 }, 
     { _id: 12345, data_hourly: 98765 }, 
     { _id: 12345, data_hourly: 98765 } 
    ]; 

    for (let item of data) { 

     let doc = await Data.findByIdAndUpdate(item._id, 
     { $addToSet: { data_hourly: { id: item.data_hourly } } }, 
     { new: true, upsert: true } 
    ); 

     log(doc); 
    } 


    } catch(e) { 
    console.error(e); 
    } finally { 
    mongoose.disconnect(); 
    } 

})(); 

這表明你的一切完美的作品:

尤其需要命名 _idid
Mongoose: datas.remove({}, {}) 
Mongoose: datas.findAndModify({ _id: 12345 }, [], { '$setOnInsert': { __v: 0 }, '$addToSet': { data_hourly: { id: 12345 } } }, { new: true, upsert: true, remove: false, fields: {} }) 
{ 
    "_id": 12345, 
    "__v": 0, 
    "data_hourly": [ 
    { 
     "id": 12345 
    } 
    ] 
} 
Mongoose: datas.findAndModify({ _id: 12345 }, [], { '$setOnInsert': { __v: 0 }, '$addToSet': { data_hourly: { id: 98765 } } }, { new: true, upsert: true, remove: false, fields: {} }) 
{ 
    "_id": 12345, 
    "__v": 0, 
    "data_hourly": [ 
    { 
     "id": 12345 
    }, 
    { 
     "id": 98765 
    } 
    ] 
} 
Mongoose: datas.findAndModify({ _id: 12345 }, [], { '$setOnInsert': { __v: 0 }, '$addToSet': { data_hourly: { id: 98765 } } }, { new: true, upsert: true, remove: false, fields: {} }) 
{ 
    "_id": 12345, 
    "__v": 0, 
    "data_hourly": [ 
    { 
     "id": 12345 
    }, 
    { 
     "id": 98765 
    } 
    ] 
} 

場與_id: false在出席模式選項。 MongoDB默認使用ObjectId,並且貓鼬模式默認使用這種方式。這是你特別需要關閉的東西,而不是"strict"這是「蠻力」,因爲根本不考慮任何模式規則。這違背了定義架構的目的。

+0

感謝您提供此答案的時間。它通過使用{strict:'throw'}間接幫助我找到問題。這只是一種類型不匹配。 Mongoose給出的最初錯誤對故障排除提供了絕對的幫助!再次感謝 – Chris