find一个或用Mongoose创build
我有
Page.findById(pageId).then(page => { const pageId = page.id; .. });
我的问题是,如果没有给出页面ID,它应该只是采取第一个可用的页面给出了一些条件,这是由
Page.findOne({}).then(page => { const pageId = page.id; .. });
但如果没有find页面,它应该创build一个新的页面,并使用它,这是完成的
Page.create({}).then(page => { const pageId = page.id; .. });
但是,我怎么把所有这些结合到尽可能less的几行呢?
我有很多逻辑在里面
page => { ... }
所以我非常想做这个聪明的,所以我可以避免这样做
if (pageId) { Page.findById(pageId).then(page => { const pageId = page.id; .. }); } else { Page.findOne({}).then(page => { if (page) { const pageId = page.id; .. } else { Page.create({}).then(page => { const pageId = page.id; .. }); } }); }
我想我也许可以分配一个静态类似的东西
pageSchema.statics.findOneOrCreate = function (condition, doc, callback) { const self = this; self.findOne(condition).then(callback).catch((err, result) => { self.create(doc).then(callback); }); };
与Yosvel Quintero的答案有关,这对我不起作用:
pageSchema.statics.findOneOrCreate = function findOneOrCreate(condition, callback) { const self = this self.findOne(condition, (err, result) => { return result ? callback(err, result) : self.create(condition, (err, result) => { return callback(err, result) }) }) }
然后像这样使用它:
Page.findOneOrCreate({ key: 'value' }, (err, page) => { // ... code console.log(page) })
每个模式可以为其模型定义实例和静态方法 。 静态方法几乎与方法相同,但允许定义直接存在于模型上的函数
静态方法findOneOrCreate
:
pageSchema.statics.findOneOrCreate = function findOneOrCreate(condition, doc, callback) { const self = this; self.findOne(condition, (err, result) => { return result ? callback(err, result) : self.create(doc, (err, result) => { return callback(err, result); }); }); };
现在当你有一个Page
的实例,你可以调用findOneOrCreate
:
Page.findOneOrCreate({id: 'somePageId'}, (err, page) => { console.log(page); });
如果你不想为模型添加一个静态方法,你可以尝试移动一些东西,至less不要有所有这些callback嵌套级别:
function getPageById (callback) { Page.findById(pageId).then(page => { return callback(null, page); }); } function getFirstPage(callback) { Page.findOne({}).then(page => { if (page) { return callback(null, page); } return callback(); }); } let retrievePage = getFirstPage; if (pageId) { retrievePage = getPageById; } retrievePage(function (err, page) { if (err) { // @todo: handle the error } if (page && page.id) { pageId = page.id; } else { Page.create({}).then(page => { pageId = page.id; }); } });
尝试这个..
var myfunc = function (pageId) { // check for pageId passed or not var newId = (typeof pageId == 'undefined') ? {} : {_id:pageId}; Page.findOne(pageId).then(page => { if (page) const pageId = page.id; else { // if record not found, create new Page.create({}).then(page => { const pageId = page.id; }); } }); }
使用承诺:
pageSchema.statics.findOneOrCreate = function(id, cb){ return (id?this.findById(id, cb):this.findOne({}, cb)) .then(page=>page? page : this.create({}, cb)) }
那么你可以像这样使用它:
Page.findOneOrCreate(pageId, (err, page)=>{ if(err){ //if theres an error, do something } // or do something with the page })
或承诺:
Page.findOneOrCreate(id) .then(page=> /* do something with page*/ ) .catch(err=> /* do something if there's an error*/ )