wake-up-neo.net

Finden Sie einen oder erstellen Sie mit Mongoose

Ich habe 

Page.findById(pageId).then(page => {
  const pageId = page.id;
   ..
});

Mein Problem ist, dass, wenn keine Seiten-ID angegeben wird, diese unter bestimmten Bedingungen nur die erste verfügbare Seite übernehmen soll

Page.findOne({}).then(page => {
  const pageId = page.id;
  ..
});

wenn jedoch keine Seite gefunden wird, sollte sie eine neue Seite erstellen und diese verwenden, was mit erledigt wird

Page.create({}).then(page => {
  const pageId = page.id;
  ..
});

Aber wie kombiniere ich das alles zu möglichst wenigen Zeilen?

Ich habe viel Logik im Inneren

page => { ... }

ich möchte das also sehr gerne schlau machen, um es so zu vermeiden

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;
        ..
      });
    }
  });
}

Ich denke, ich könnte dem Schema vielleicht eine Statik zuweisen

pageSchema.statics.findOneOrCreate = function (condition, doc, callback) {
  const self = this;
  self.findOne(condition).then(callback).catch((err, result) => {
    self.create(doc).then(callback);
  });
};
11
Jamgreen

Verwandt mit Yosvel Quinteros Antwort, die für mich nicht funktionierte:

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) })
    })
}

Und dann verwenden Sie es wie:

Page.findOneOrCreate({ key: 'value' }, (err, page) => {
    // ... code
    console.log(page)
})
6
David Joos

Nach dem Mongoose docs :

Wie in vorherige SO Antwort

Model.findByIdAndUpdate ()

"Findet ein übereinstimmendes Dokument, aktualisiert es entsprechend dem Aktualisierungsargument, übergibt alle Optionen und gibt das gefundene Dokument (falls vorhanden) an den Rückruf zurück."

In den Optionen, die auf true gesetzt sind:

upsert: bool - erstellt das Objekt, falls es nicht existiert. Der Standardwert ist "false".

Model.findByIdAndUpdate(id, { $set: { name: 'SOME_VALUE' }}, { upsert: true  }, callback)
12
Julian Boyce

Jedes Schema kann Instanz- und statische Methoden für sein Modell definieren. Statik ist im Wesentlichen dasselbe wie Methoden, erlaubt jedoch die Definition von Funktionen, die direkt in Ihrem Modell vorhanden sind

Statische Methode 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);
      });
  });
};

Wenn Sie jetzt eine Instanz von Page haben, können Sie findOneOrCreate aufrufen:

Page.findOneOrCreate({id: 'somePageId'}, (err, page) => {
  console.log(page);
});
8
Yosvel Quintero

Versprechen Sie async/await Version.

Page.static('findOneOrCreate', async function findOneOrCreate(condition, doc) {
  const one = await this.findOne(condition);

  return one || this.create(doc);
});

Verwendungszweck

Page.findOneOrCreate({ id: page.id }, page).then(...).catch(...)

Oder

async () => {
  const yourPage = await Page.findOneOrCreate({  id: page.id }, page);
}
5
Ninh Pham

Einzeilige Lösung mit async/await:

const page = Page.findOne({}).then(p => p || p.create({})

3
Pooya

Versprechungen verwenden:

pageSchema.statics.findOneOrCreate = function(id, cb){
  return (id?this.findById(id, cb):this.findOne({}, cb))
  .then(page=>page? page : this.create({}, cb))
}

dann kannst du es so benutzen: 

Page.findOneOrCreate(pageId, (err, page)=>{
  if(err){
    //if theres an error, do something
  }
  //  or do something with the page
})

oder mit Versprechen:

Page.findOneOrCreate(id)
.then(page=> /* do something with page*/ )
.catch(err=> /* do something if there's an error*/ )
0
flakolefluk

Wenn Sie dem Modell keine statische Methode hinzufügen möchten, können Sie versuchen, einige Dinge zu verschieben und zumindest nicht alle diese Callback-Ebenen zu haben:

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;
    });
  }
});
0

versuche dies.. 

 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;
    });
  }
});

 }
0
Umakant Mane