Push value to Array if key does not exist Mongoose [duplicate] - node.js

This question already has answers here:
Mongoose Unique values in nested array of objects
(2 answers)
Closed 8 years ago.
Given mongoose schema
var SomeSchema = new Schema({
// ...
members: [
{
name: String,
username: String
}
]
});
From my code I want to push object to members but only if there is no given username in array yet. How can I do it with mongoose?

You could check for the username in the condition part of the update query:
var conditions = {
_id: id,
'members.username': { $ne: 'something' }
};
var update = {
$addToSet: { members: { name: 'something', username: 'something' } }
}
SomeModel.findOneAndUpdate(conditions, update, function(err, doc) {
...
});

Related

Get table A values with table B where A.field_name = B.field_name [duplicate]

This question already has answers here:
How do I perform the SQL Join equivalent in MongoDB?
(19 answers)
Closed 3 years ago.
In back end I'm using mongoose, express and node js. I want to do joins in mongodb. If this is SQL it's not hard. Since I'm new to mongo database. This is problem to me. I already tried many answers in this platform and none of them help my situation.
I have following two schema in my database.
Item
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
export const item_schema = new Schema({
item_no: {
type: String
},
name: {
type: String
},
item_category: {
type: String
},
no_of_copies: {
type: Number
},
public_or_rare: {
type: String
},
user_no: {
type: String
}
});
Book
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
export const book_schema = new Schema({
item_no: {
type: String
},
isbn_no: {
type: String
},
author: {
type: String
},
published_year: {
type: Number
},
publisher: {
type: String
},
book_category: {
type: String
}
});
Note that there is no error in these models because those runs well with other controllers in my API
I want to get book and item tables data as one object where book and item share same item_no
In order to achieve my aim so far I tried following code,
export const get_books_all_details = (req, res) => {
Book.find({}, (err, book) => {
if (err) {
res.send(err);
}
else {
let my_book = book;
// res.json(my_book);
Item.findOne({ item_no: my_book.item_no }, (err, item) => {
//Item.find({}, (err, item) => {
if (err) {
res.send(err);
}
else {
let my_item = item;
//res.send(my_book+my_item);
res.json({
/* item_no: my_item.item_no,
item_name: my_item.item_name,
item_category: my_item.item_category,
no_of_copies: my_item.no_of_copies,
public_or_rare: my_item.public_or_rare,
isbn_no: my_book.isbn_no,
author: my_book.author,
published_year: my_book.published_year,
publisher: my_book.publisher,
book_category: my_book.book_category , */
book:my_book,
item:my_item
})
}
});
}
});
};
In top I use find() to get all books and if there is record in item table which matches item_no I want to get that particular item too. That's why I used findOne() inside find()
I don't know is it right or wrong !
So this new guy wait for you guys help and really appreciate it. If you could help me with code and explanations that will be great !
I want to do joins in mongodb
Just don't. MongoDB is a NoSQL database, specifically built to avoid joins and to enforce denormalization of data. If you need to join a document, put it inside of another document. If you build your collections in MongoDB like you do in any SQL database, you'd just have a non ACID compliant relational database, which is dangerous.

Get the _id of the sub-document from mongoose findOne query

The schema of my Sample model is:-
var nameSchema = new mongoose.Schema({
firstname:String,
lastname:String
})
var sampleSchema= new mongoose.Schema({
number: {
type: String
},
name :{
type : [nameSchema]
}
});
I am trying to update the first and last name by searching them by their number property by making use of Sample.findOne({number:number}). And i am performing the update operation in the following manner:-
module.exports.updateNumber = function(req, res){
var number= req.body.number;
var lname= req.body.lname;
var fname= req.body.fname;
Sample
.findOne({number:number})
.select('name')
.exec(function(err, doc){
console.log(doc)
var this_id;
var thisService = doc.name.id('this_id');
thisService.firstname=fname;
thisService.lastname=lname;
doc.save(function(err, update) {
if (err) {
res
.status(500)
.json(err);
} else {
res
res.render('done')
}
});
})
}
If i console log the output i got is:
{ _id: 5bc5d71f47ff14361c0639d1,
name:
[ { _id: 5bc5d71f47ff14361c0639d2,
firstname: 'firstname',
lastname: 'lastname' } ] }
Is there any way, i could store _id: 5bc5d71f47ff14361c0639d2 in 'this_id' variable, so that this updation would be possible
name is an array, so if you want the first _id then name[0]._id would suffice, if you want an array of all values for _id in name, then name.map((person) => person._id) would give you an array of _id
However, more details about the context of this object would help give a better answer.

Mongoose: How to push in nested array? [duplicate]

This question already has answers here:
Updating a Nested Array with MongoDB
(2 answers)
Closed 3 years ago.
I am very new to NoSQL world. Here the screenshot of my Mongoose schema.
I need to insert,update and delete document to/from vehicles array.
What I have tried so far:
Add: (Working)
Companies.findOne({'mobile' : givenMobileNumber, 'VehicleGroups.vehicle_group_id' : vehicleGroupId}, (err, res) => {
if( err || res == null) {
callback(err, res);
}else{
var len = res.VehicleGroups.length;
for(var i=0; i<len; i++)
{
if(res.VehicleGroups[i].vehicle_group_id == vehicleGroupId)
res.VehicleGroups[i].vehicles.push(data);
}
res.save(callback);
}
})
Delete: (Working)
Companies.findOneAndUpdate({ mobile : givenMobileNumber, 'VehicleGroups.vehicle_group_id' : vehicleGroupId},
{ $pull : {'VehicleGroups.$.vehicles' : { 'vehicle_id' : vehicleId} } }, callback);
Still working to update data. Is my approach valid?
Thanks
You can consider setting up separate schemas for your VehicleGroups and vehicles and reference them through ObjectId in your Companies schema:
VehicleGroups: [{
_id: { type: Schema.Types.ObjectId, ref: 'vehicleGroup' },
// All other properties here
vehicles: [{ type: Schema.Types.ObjectId, ref: 'vehicle' }]
}]
Adding a new document to theVehicleGroup schema would then go something like this:
const newVehicleGroup = new VehicleGroup({
name: 'New Vehicle',
// Set all other fields
})
And adding it to the Companies schema:
Companies.findOneAndUpdate({
mobile : givenMobileNumber, 'VehicleGroups.vehicle_group_id' : vehicleGroupId,
{ $push: { vehicleGroups: newVehicleGroup._id } }
})
Since you reference vehicles and VehicleGroups by ObjectId, all you have to do to update that reference is to update the document in the respective collection.
However, if you delete a document you will need to remove its reference from the respective array in the Companies collection.
See if this approach makes it a little easier!

Issue in saving values in array in mongoose model using save() [duplicate]

This question already has answers here:
Push items into mongo array via mongoose
(11 answers)
Closed 5 years ago.
I am trying to update a document in a collection. I am particularly trying to update an array of Strings.The following is my Schema
var sampleSchema= mongoose.Schema({
fullName : String,
email : String,
rolesTaken : [String],
});
I basically have an array of such schema's. I want to update the rolesTaken array for all of them.
So I did the following
var async = require('async');
var ATmapping = require('path to Schema');
ATmapping.find({},function(err,lists){
if(err){
console.log(err);
return;
}
if(lists.length > 0){
async.each(lists,function(list,callback){
if(!list.rolesTaken){
list.rolesTaken =[];
}
list.rolesTaken.push("Patient");
list.markModified('rolesTaken');
list.save(function(err,item){
if (err){
console.log(err);
}
console.log('Saved', item);
callback();
});
});
}
});
I have browsed a lot and the most popular solution was to add markModified. But it doesn't seem to work in my case.When I added mongoose.debug i got the following
atmappings.update({ _id: ObjectId("59074b127adeef0004b84ac3"), __v: 7 }, { '$set': { rolesTaken: [] }, '$inc': { __v: 1 } })
As you can see the roles taken is empty despite me adding markmodified and save(). I would like to know if I am missing something which is preventing me from saving the values in the schema.
Thanks in advance.
Here is how I push a comment to a thread in one of my apps using mongoose.
Thread.findByIdAndUpdate(body.thread, { $push: { comments: comment.id }})
I simply find the thread by the id, then use the $push operator to push the comment id to the comments attribute where I populate later.
You can read more into the $push operator here (mongoose v3.4) https://docs.mongodb.com/manual/reference/operator/update/push/

How to get a specific object from an array field with mongoose [duplicate]

This question already has answers here:
Retrieve only the queried element in an object array in MongoDB collection
(18 answers)
Closed 8 years ago.
Given a schema like this:
UserSchema = new Schema({
name: String,
donations: [
{
amount: Number,
charity: {
type: Schema.Types.ObjectId,
ref: 'charity'
}
}
]
});
I have the (string) ids of a user and of a nonprofit and I want to get the amount the user donated. Im using this query with lodash:
User.findOne({
_id: userId
}, function(err, user) {
var amount = _.find(user.donations, {charity: charityId});
console.log("the amount is: ", amount);
});
Here the amount returns undefined even though it shouldn't also im guessing i shouldn't have to use lodash. What's the right way to get to the amount donated given a specific userId and charityId?
This is pretty similar to the possible duplicate I linked to, as you can do this without using lodash as:
User.findOne({
_id: userId,
'donations.charity': charityId
}, {
'donations.$': 1
}, function(err, user) {
console.log("the amount is: ", user.donations[0].amount);
});

Resources