mongodb - Insert multiple documents referenced by another Schema -


i have following 2 schemas:

var schemaone = new mongoose.schema({   id_headline: { type: string, required: true },   tags: [{ type: mongoose.schema.types.objectid, ref: 'tag' }] });  var tagschema = new mongoose.schema({   _id: { type: string, required: true, index: { unique: true } }, // value   name: { type: string, required: true } }); 

as can see, in first schema there array of references second schema.

my problem is:

suppose that, in backend server, receive array of tags (just id's) and, before creating schemaone document, need verify if received tags exist in database and, if not, create them. after having tags stored in database, may assign received array tags array of created schemaone document.

i'm not sure on how implement this? can give me helping hand?

so lets assume have input being sent server resolves this:

var input = {     "id_headline": "title",     "tags": [         { "name": "one" },         { "name": "two" }     ] }; 

and state, not sure whether of "tags" entries alredy exists, of course "name" unique lookup associated object.

what going have here "lookup" each of elements within "tags" , return document reference use objects in "tag" model. ideal method here .findoneandupdate(), "upsert" option set true. create document in collection not found, , @ rate return document content reference created.

note natually, want ensure have array items resolved "first", before preceeding saving main "schemaone" object. async library has methods structure this:

async.waterfall(     [         function(callback) {             async.map(input.tags,function(tag,callback) {                 tag.findoneandupdate(                     { "name": tag.name },                     { "$setoninsert": { "name": tag.name } },                     { "upsert": true, "new": true },                     callback                 )             },callback);         },         function(tags,callback) {             model.findoneandupdate(                 { "id_headline": input.id_headline },                 { "$addtoset": {                      "tags": { "$each": tags.map(function(tag) { return tag._id }) }                 }},                 { "upsert": true, "new": true },                 callback             )         }     ],     function(err,result) {         // if err report it, otherwise it's done.     } ) 

so async.waterfall special flow control method pass result returned each of functions specified in array of arguments next one, right until end of execution can optionally pass in result of final function in list. "cascades" or "waterfalls" results down each step. wanted pass in results of "tags" creation main model creation/modification.

the async.map within first executed stage looks @ each of elements within array of input. each item contained in "tags", .findoneandupdate() method called , possibly create if not found, specified "tag" entry in collection.

since output of .map() going array of documents, passed through next stage. therefore each iteration returns document, when iteration complete have documents.

the next usage of .findoneandupdate() "upsert" optional, , of course considers document matching "id_headline" may or may not exist. same case true if there "update" processed, if not created. optionally .insert() or .create() if document known not there, "update" action gives interesting options.

namely here usage of $addtoset, if document existed specified items "added" content there, , of course "set", items present not new additions. note _id fields required here when adding array atomic operator, hence .map() function employed.

an alternate case on "updating" "replace" array content using $set atomic operation if intent store items mentioned in input , no others.

in similar manner $setoninsert shown when "creating"/"looking for" items in "tags" makes sure there actual "modification" when object "created/inserted", , removes write overhead on server.

so basic priciples of using .findoneandupdate() @ least "tags" entries optimal way of handling this. avoids double handling such as:

  • querying see if document exists name
  • if no result returned, send additional statement create one

that means 2 operations database communication , forth, actions here using "upserts" simplifies single request each item.


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -