Mongoose, Add/Update data to a set of documents of a collection - node.js

Hello guys here's the situation of my problem:
My Categories model looks like this:
schema: {
_id: String,
name: String,
overview: String,
courses: [
{
_id: String,
name: String
}
]
}
I have multiple categories recorded, in the above collection Categories
WHAT I NEED
I have an [ array ] of Categories._id like this:
[
'5812f3cb04700f2563c0e56a',
'5812f3ff04700f2563c0e56b',
...
]
All I want is to PUSH this object {_id:5812f3ff04700f2563c0e56b, name:'SOMETHING' } to all the documents listed in the array of _id
WHAT I TRIED
Categories.update({
'_id': {
$in : array_of_IDs
}
},
{
$push :{
'courses':{ _id: ret._id , name: ret.title }
}
}, function(err, respp){
if(err) return res.negotiate(err);
else{
req.addFlash('success', 'Categories updated successfully.');
return res.redirect('/new-course');
}
}
);
This above code is updating only one collection (the collection with 1st ID in the array of IDs)
Please help!
Thanks

can try using multi: true as option
Categories.update({
'_id': {
$in : array_of_IDs
}
},
{
$push :{
'courses':{ _id: ret._id , name: ret.title }
}
},{ multi: true }, function(err, respp){
//....
}
);

Related

Pull element from an array of arrays MongoDb

I am struggling to find the format for a query to remove an element (with an _id) from an array of arrays in Mongo.
When looking at the docs I couldn't find anything that was similar to what I have
https://www.mongodb.com/docs/manual/reference/operator/update/pull/#up._S_pull
I know: the _id of the document in MySchema and the _id of the array element in innerArray.
I don't know the outerArray _id
Could someone help point out where I went wrong Thank you!
This is an example of the data (imagine the _id in ObjectId)
{
outerArray:[
{
_id: 1
innerArray: [{_id: 23, name: '123'}, {_id: 13, name: 'asdac'} ]
},
{
_id: 2,
innerArray: [{_id: 16,name:'asf' }, {_id: 18,name:'asf' } ]
},
{
_id: 3,
innerArray: [{_id: 136,name:'asf' }, {_id: 128,name:'asf' } ]
}
]
}
innerIds is an array of mongoose.Types.ObjectId
return MySchema.updateOne(
{
_id: documentId,
},
{ $pull: { outerArray: { innerArray: { _id: { $in: innerIds } } } } },
)
.session(session)
.exec()
db.collection.update({},
{
$pull: {
"outerArray.$[].innerArray": {//$[] does the trick
_id: {
$in: [
16
]
}
}
}
})
playground

Mongoose add/remove items from nested array

I have a document that has a nested array that I need to add/remove items from. Normally you query a nested object by id but in this case a dynamic object _id wont work and I need to update by the nested profile id.
Document
{
title: 'Title',
members: [
{
profile: { id: '123', name: 'Foo' },
items: ['id1', 'id2', 'id3']
}
]
}
Query
My thinking is I need some sort of $elemMatch & $pushAll combo but cant seem to get it working. For removing items from the array I would swap push for pull
await this.repo.findByIdAndUpdate(id, {
members: {
$elemMatch: { 'profile.id': '123' },
$pushAll: {
items: ['xxx', 'yyy'],
},
},
})
You need to use arrayFilters & $push with $each since $pushAll has been deprecated
db.collection.update({},
{
$push: {
"members.$[x].items": {
$each: [
"xxx",
"yyy"
]
}
}
},
{
arrayFilters: [
{
"x.profile.id": "123"
}
]
})
playground

Mongoose findOneAndUpdate updating as ObjectId

I have the following schema:
let PlayerSchema = new mongoose.Schema( {
name: String,
country: String,
roundResults: [ {
round: Number,
result: String,
points: Number
} ]
} );
When I use findOneAndUpdate to update a document:
Player.findOneAndUpdate({ id: req.params.id },
{$push: {"roundResults": result }},
{safe: true, upsert: true, new : true},
(err, player) => {
if( ! err && player ) {
res.json( player );
} else {
res.json( err );
}
}
);
I get the following unexpected result:
[
{
"_id": "57c9eb55c2a07a401462e3ec",
"name": "Joe Bloggs",
"country": "England",
"__v": 0,
"roundResults": [
{
"_id": "57c9eba11c597d5e1460e4f0"
}
]
}
]
I don't have a roundResults schema but, I get an _id as shown above, I would expect to see,:
"roundResults": [
"round": 1,
"result": "1",
"points": 3
]
Can anyone explain why this is, or how I get this to nest the data I am displaying directly above?
Even if you pass literal object for sub documents, it is a Schema. And id would be generated for that. If it is an array define its type Array.
Attention that if you define any schema for a property it is considered as a subdoc and entity so it has id

If condition query for mongo db

I have an collection with documents that can be public or private. I am looking to have a single query that can get a document by an _id and check if it's private. If it is private it needs to check if the user requesting the document is a participant in the object.
Here is the object:
{
"_id" : ObjectId("5769ae620e80ea1c7f8a997f"),
"owner" : ObjectId("5740edae95a1b4c043d033df"),
"private" : false,
"participants" : [
{
"uid" : ObjectId("5740edae95a1b4c043d033df"),
"notify" : true
}
],
"messages" : [ ]
}
This is the 2 step query I wrote and wondering if I can simplify it
function getRoom(roomId, user){
db.rooms.findOne({ _id: pmongo.ObjectId(roomId) })
.then(room => {
if(room.private){
return db.rooms.findOne({
_id: pmongo.ObjectId(roomId),
participants: {$eleMatch: {uid: String(user._id)}}
})
} else {
return room
}
})
}
Any help would be great!
MongoDB has $or operator which can be used in this case:
db.rooms.findOne({ $or: [
{
_id: pmongo.ObjectId(roomId),
private: { $ne: true }
}, {
_id: pmongo.ObjectId(roomId),
participants: {$eleMatch: {uid: String(user._id)}}
}
]})

Find object id in object ids array returns empty array using Mongoose

I have two Mongoose schemas:
var EmployeeSchema = new Schema({
name: String,
servicesProvided: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Service'
}]
});
var ServiceSchema = new Schema({
name: String
});
I'm trying to find employees who provide a specified service with the service ID I send into the http request. This is my code:
Employee
.find({
servicesProvided: req.params.service_id
})
.exec(function(err, employees) {
if (err) {
console.log(err);
res.send(err);
} else {
res.json(employees);
}
});
The problem is that this code returns an empty array and I don't know why. I've tried a lot of things like casting the service id to mongoose.Schema.Types.ObjectId but it doesn't work.
Any idea? I'm using Mongoose 3.8.39. Thanks!
In your EmployeeSchema, servicesProvided is an array, to filter employees by that field you should use $in operator:
var services = [req.params.service_id];
Employee.find({
servicesProvided: {
$in: services
}
}, ...
I think you need $elemMatch! From docs:
{ _id: 1, results: [ { product: "abc", score: 10 }, { product: "xyz", score: 5 } ] },
{ _id: 2, results: [ { product: "abc", score: 8 }, { product: "xyz", score: 7 } ] },
{ _id: 3, results: [ { product: "abc", score: 7 }, { product: "xyz", score: 8 } ] }
Search like:
db.survey.find({ results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } })
Results in:
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, { "product" : "xyz", "score" : 8 } ] }
But since you're doing a single query condition (look at the docs again) you can replace
db.survey.find(
{ results: { $elemMatch: { product: "xyz" } } }
)
with
db.survey.find(
{ "results.product": "xyz" }
)
So in your case it should be something like:
find({
'servicesProvided': ObjectId(req.params.service_id)
})

Resources