Last active
January 30, 2016 07:15
-
-
Save btkostner/d97f767afc6f8d0b4f28 to your computer and use it in GitHub Desktop.
upsert (update or create) a nested array in mongoose near atomicly without save function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import mongoose from 'mongoose'; | |
| import _ from 'lodash'; | |
| import dotize from 'dotize'; | |
| ApplicationSchema.methods.upsertRelease = function(query, object) { | |
| const application = this; | |
| // Create an object from query using dot notation instead of objects ('releases.github.id') | |
| const dotQuery = dotize.convert(query, 'releases'); | |
| // Create an object of values to update to, uses mongoose's $ operator | |
| const dotUpdate = dotize.convert(object, 'releases.$'); | |
| // Create a new object of dotQuery, but with mongodb's not operator for value | |
| const notDotQuery = _.mapValues(dotQuery, value => ({ $ne: value })); | |
| return Promise.all([ // Return two promises, one for update, and one for insert | |
| Application.update(_.extend({ // Find an application with same _id, and includes release query | |
| _id: application._id, | |
| }, dotQuery), dotUpdate), // Use generated dotUpdate object for updating | |
| Application.update(_.extend({ // Find an application that has _id but does NOT include release (avoids adding when already exists) | |
| _id: application._id, | |
| }, notDotQuery), { | |
| $addToSet: { | |
| releases: object, // Push new release into array | |
| }, | |
| }), | |
| ]); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This function comes in handy when using promises that run in parallel. It does not use any
.save()functions, so it will never be using out of date information to calculate existence. It depends on one of the functions failing while the other succeeds, hence the not query in the second function.