2016-02-26 71 views
1

我是新來的貓鼬作爲更新Mongo的方法。我正在使用nmap來映射我的網絡,並提供一些關於服務器和端口的可見性(作爲較大策略的一部分)。這一部分策略alos從CHEF和vSphere中提取信息,這些信息都在GUI中鏈接在一起。這些部分只是簡單的單級對象,並且工作正常,但是NMAP部分具有父/子對象模型。該對象模型有一個Server對象和一個Port對象 - 兩者都添加了onOn和updatedOn日期。Mongoose Pre保存掛鉤父對象不執行

不幸的是,預存儲的mongoose鉤子只會觸發子對象(每個對象)而不是父對象 - 儘管父對象正在保存。 我真的希望父對象也有addedOn和updatedOn日期。我似乎無法弄清楚。在此先感謝

一個免責聲明,下面的代碼被剪掉了一個用民間故事,ramda和點自由形式寫的大型應用程序。

5.1的NodeJS,貓鼬4.4.1

的port.js文件

const mongoose = require('mongoose'); 

const Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 

const PortSchema = new Schema({ 
    id    : ObjectId, 
    port    : String, 
    protocol   : String, 
    application  : String, 
    addedOn   : { type: Date, default: Date.now, setDefaultsOnInsert: true }, 
    updatedOn  : { type: Date, default: Date.now } 
}); 

PortSchema.pre('save', function(next){ 
    this.update({},{ 
     $set: { 
      updatedOn: new Date() 
     } 
    }) 
    next(); 
}); 

module.exports.model = mongoose.model('Port', PortSchema) 
module.exports.schema = PortSchema 

的server.js文件

const mongoose = require('mongoose'); 
const PortSchema = require('./port').schema 

const Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 

const ServerSchema = new Schema({ 
    id    : ObjectId, 
    address   : String, 
    addressType  : String, 
    ports   : [PortSchema], 
    addedOn   : { type: Date, default: Date.now, setDefaultsOnInsert: true }, 
    updatedOn  : { type: Date, default: Date.now } 
}); 

ServerSchema.pre('save', function(next){ 
    this.update({},{ 
     $set: { 
      updatedOn: new Date() 
     } 
    }) 
    next(); 
}); 


module.exports.model = mongoose.model('Server', ServerSchema) 
module.exports.schema = ServerSchema 

的Upsert代碼在我的應用

// nmapUpsert :: (criteria, {}) => Task {ok :: int, ...} 
const nmapUpsert = adapt.findOneAndUpdate(Server) 


// persist :: [{address :: string, ...}] => [Task {ok :: int, ...}] 
const persistNmap = R.map((data) => { 
    return nmapUpsert({ "address": data.address }, data) 
}) 

這是我的模型 - >任務UPSERT適配器(adapt.findOneAndUpdate)

module.exports.findOneAndUpdate = (originalModel) => { 
    return (criteria, record) => { 

     return new Task((reject, resolve) => { 
      const callback = (error, updatedModel) => { 
       if (error) { 
        reject(error) 
       } 
       else { 
        if(!updatedModel) { 
         resolve(null) 
        }else { 
         // this looks to be required to apply defaults from the Schema 
         updatedModel.save((error) => { 
          if (error) { 
           reject(error) 
          } 
          resolve(updatedModel) 
         }) 
        } 

       } 
      } 

      originalModel.findOneAndUpdate(criteria, record, {upsert: true}, callback) 
     }) 

    } 
} 

不可否認的是最後一個函數是有點cludgy - 但我只是想弄清楚這之前,我清理。

+0

'預save'鉤不上'update'運行。你應該可以添加一個'更新前'鉤子。讓我知道這是否有效。 – Mike

+0

@Mike更新掛鉤無法正常工作,但我將Server.js上的掛鉤更改爲「findOneAndUpdate」掛鉤,而且似乎可以在該層上工作。現在底層端口不更新。我需要調查一下。 – akaphenom

回答

0

如果我改變鉤子findOneAndUpdate我會得到更好的行爲。服務器將insertOn(和updatedOn)上的addedOn對象化,然後只更新updatedOn。 Unforutnately整個Ports對象集合被取代 - 即使在更新時 - 並且addedOn和updatedOn都會在此時更新。

的port.js文件

const mongoose = require('mongoose'); 

const Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 

const PortSchema = new Schema({ 
    id    : ObjectId, 
    port    : String, 
    protocol   : String, 
    application  : String, 
    addedOn   : { type: Date, default: Date.now, setDefaultsOnInsert: true }, 
    updatedOn  : { type: Date, default: Date.now } 
}); 

PortSchema.pre('findOneAndUpdate', function(next){ 
    this.update({},{ 
     $set: { 
      updatedOn: new Date() 
     } 
    }) 
    next(); 
}); 

module.exports.model = mongoose.model('Port', PortSchema) 
module.exports.schema = PortSchema 

的server.js文件

const mongoose = require('mongoose'); 
const PortSchema = require('./port').schema 

const Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 

const ServerSchema = new Schema({ 
    id    : ObjectId, 
    address   : String, 
    addressType  : String, 
    ports   : [PortSchema], 
    addedOn   : { type: Date, default: Date.now, setDefaultsOnInsert: true }, 
    updatedOn  : { type: Date, default: Date.now } 
}); 

ServerSchema.pre('findOneAndUpdate', function(next){ 
    this.update({},{ 
     $set: { 
      updatedOn: new Date() 
     } 
    }) 
    next(); 
}); 


module.exports.model = mongoose.model('Server', ServerSchema) 
module.exports.schema = ServerSchema