Remove entry from double nester array using mongoose - node.js

I'm trying to remove an entry from an array which nested in another array as you can see below:
{
"_id" : ObjectId("548f5ca9fa9dc1000016a725"),
"entries" : [
{
"_id" : ObjectId("548f5cc8fa9dc1000016a726"),
"content" : [
{
"order" : ObjectId("5489fa9127f1310000bea2ed"),
"order_id" : "305429245",
"item_id" : "305429245-1"
},
{
"order" : ObjectId("5489fa9127f1310000bea2ce"),
"order_id" : "330052901",
"item_id" : "330052901-1"
}
],
"stop_number" : 1
},
{
"stop_number" : 2,
"expected_arrival" : ISODate("2014-12-15T17:11:11.000Z"),
"expected_departure" : ISODate("2014-12-15T19:03:17.000Z"),
"_id" : ObjectId("548fb2826e52c20000bd2299"),
"content" : []
}
]
}
And i'm trying to remove the entry that have '305429245-1', so i used:
Q.npost(Manifests, 'findOneAndUpdate', [
{ '_id': id },
{
'$pull': {
'entries.content': { item_id: line_item_id }
}
}
])
where 'id' is the ObjectID (548f5ca9fa9dc1000016a725) and line_item_id = 305429245-1, however, this doesn't work. Can anyone let me know what am i doing wrong?

Try to use find and Update functions separately instead of findOneAndUpdate
Model.find({'_id: id'},function(err,callback){...})
{
//handle callback
}
Model.update({'_id: id'}, {$pull: {'entries.content': item_id: line_item_id}}, function(err,callback){..} )
{
//do some logic or handle callback
}
here Model which i mentioned,should be the model you are using.

Related

How to project specific elements in an Array field in MongoDB?

I have this data in MongoDB:
{
"_id" : ObjectId("5c7e459f875ea5548de25722"),
"Autos" : [
{
"_id" : ObjectId("5cad9759e1c3895999adaceb"),
"deleted" : 1,
},
{
"_id" : ObjectId("5cad9a8be1c3895999adacef"),
"deleted" : 0,
},
{
"_id" : ObjectId("5cad9aa4e1c3895999adacf0"),
"deleted" : 0,
}
]
}
{
"_id" : ObjectId("5c7e45e9875ea5548de25724"),
"Shoemaking" : [
{
"_id" : ObjectId("5cad9770e1c3895999adacec"),
"deleted" : 1,
},
{
"_id" : ObjectId("5cad9a5de1c3895999adaced"),
"deleted" : 0,
},
]
I want to basically select * from table where deleted = 0
show where the deleted records are equal to 0.
Here is what I have tried so far:
db.rental.find({"Autos.deleted":{$ne: 1}}).pretty()
db.rental.find({"Autos": {$elemMatch: {deleted: 1 } } } ).pretty()
db.rental.find({"Autos.deleted": 0},{"Autos": {$elemMatch:
{deleted:0}}});
But none of the above work for me. What am I doing wrong?
Desired output:
{
"_id" : ObjectId("5c7e459f875ea5548de25722"),
"Autos" : [
{
"_id" : ObjectId("5cad9a8be1c3895999adacef"),
"deleted" : 0,
},
{
"_id" : ObjectId("5cad9aa4e1c3895999adacf0"),
"deleted" : 0,
}
]
}
{
"_id" : ObjectId("5c7e45e9875ea5548de25724"),
"Shoemaking" : [
{
"_id" : ObjectId("5cad9a5de1c3895999adaced"),
"deleted" : 0,
},
]
}
I want the output to be something like the above, but all the queries I have tried so far either select only one record of Array or select nothing at all.
db.rental.aggregate([
{
$project: {
Autos: {
$filter: {
input: "$Autos",
as: "auto",
cond: { $eq:["$$auto.deleted",0] }
}
}
}
}
])
db.rental.find({ "Autos.deleted": { $eq: 0 } } )
use $elemMatch to match contain inside array. mongodb-$elemMatch
db.rental.find({
Autos: {
$elemMatch: {
deleted: 0
}
}
})

want to update only value element of specific key on mongodb

I have a dataset like this:
{
"_id" : ObjectId("5a7bee68996b551034015a15"),
"sequenceid" : 1,
"fruit" : [
{
"name" : "#APPLE",
"value" : 2
},
{
"name" : "#BANANA",
"value" : 1
},
{
"name" : "#ORANGE",
"value" : 5
}
}
want to update only Apple value i.e from 2 to 25. Expected result will be:
{
"_id" : ObjectId("5a7bee68996b551034015a15"),
"sequenceid" : 1,
"fruit" : [
{
"name" : "#APPLE",
"value" : 25
},
{
"name" : "#BANANA",
"value" : 1
},
{
"name" : "#ORANGE",
"value" : 5
}
}
I tried the code but this will replace all entry and do only one entry. My code is
db.Collection.update({'sequenceid': 1}, {$set: {'fruit' : {'name': '#APPLE', 'value': parseFloat(25)}}}, function(error, result){
if(error){
console.log('error');
} else {
console.log('success');
}
});
It can produce the result:
{
"_id" : ObjectId("5a7bee68996b551034015a15"),
"sequenceid" : 1,
"fruit" : [
{
"name" : "#APPLE",
"value" : 25
}
}//Delete all my rest entry
How I can Do this. I am a newbie on MongoDB
This will update only the first occurrence of record.For reference MongoDB - Update objects in a document's array (nested updating)
db.collection.update({ _id: ObjectId("5a7bf5586262dc7b9f3a8422") ,"fruit.name" : "#APPLE"},
{ $set:
{
"fruit.$.value" : 25
}
})
If you are writing JavaScript query then you can update like this
db.collection.find({'sequenceid': 1}).forEach(function(x){
x.fruit.forEach(function(y){
if(y.name=="#APPLE")
{
y.value = 25
}
})
db.collection.update({_id:x._id},x)
})
db.Collection.update({
_id: ObjectId("5a7bee68996b551034015a15"),
"fruit": {
$elemMatch: {
"name": "#APPLE"
}
}
}, {
$set: {
"fruit.$.value": 25
}
})
In above update operation $elemMatch operator is used to search a value in an array and in $set stage positional operator $ is used to update value of specific key belonging to an array element

Node : Mongoose Updating User Schema with arrays

Here is my User Schema
{
"user_collection":[
{
"_id":"xxx",
"name":"NAME",
"prescription":
{
"doctor_id":
[{
"_id":"xxx",
"medicine_id":"MEDICINE_ID",
}]
},
"meal":{
"meal_name":{
"start_time":"START_TIME",
"end_time":"END_TIME"
}
},
"created_at":"CREATED_AT",
"updted_at":"UPDATED_AT"
}
]
}
Note : _id given just for understanding
I need to insert document inside the prescription array. Here is the condition
If the new doctor_id is given, it should add in the prescription array like
{
"_id" : ObjectId("5813288eaa0f1231de477d92"),
"name" : "andrew",
"prescription" : [
{
"prescription" : [
{
"_id" : ObjectId("58143d484e26a229873b0528"),
"medicine_id" : "10011241343"
}
],
"_id" : ObjectId("58143d484e26a229873b0527"),
"doctor_id" : "5813221ace684e2b3f5f0a6d"
}
]
}
And if i given the doctor_id that already exists it should add like
{
"_id" : ObjectId("5813288eaa0f1231de477d92"),
"name" : "andrew",
"prescription" : [
{
"prescription" : [
{
"_id" : ObjectId("58143d484e26a229873b0528"),
"medicine_id" : "10011241343"
}
],
"prescription" : [
{
"_id" : ObjectId("58143d484e26a229873b0529"),
"medicine_id" : "10011241349"
}
],
"_id" : ObjectId("58143d484e26a229873b0527"),
"doctor_id" : "5813221ace684e2b3f5f0a6d"
}
]
}
What i have tried is
dbModel.user.update({
_id: req.body.user_id
}, {
$set: {
prescription: [ { "doctor_id" : req.body.doctor_id, "prescription" : [
{
"medicine_id" : req.body.medicine_id
}]} ],
}
}, {
upsert: true
}, function(err) {
if (err) {
res.status(202).json({
"success": "0",
"message": err
})
} else {
res.status(200).json({
"success": "1",
"message": "Prescription given successfully"
});
}
})
I don't know how to check whether the doctor_id already exists and if it does not exists it should add a new array, and if it exists it should add inside the existing arrays
Take a look in this answer.
But basically you can use the $ operator which identifies an element in an array.
You can see here some mongodb array operators.

Removing An Object From An Array ($pull doesn't seem to work)

I'm trying to remove a lesson based on lesson_id from the following.
{
"_id" : ObjectId("5807f3f"),
"title" : "Title",
"lessons" : [
{
"lesson_id" : ObjectId("58073"),
"_id" : ObjectId("58074")
},
{
"lesson_id" : ObjectId("5807f5"),
"_id" : ObjectId("5807f6")
},
{
"lesson_id" : ObjectId("58077"),
"_id" : ObjectId("5807f4")
}
],
"__v" : 0
}
I've tried $pull and $unset, but with both my code seems to just set lessons.lesson_id to null and keep the lessons._id
Is there anyway to remove both from the object?
module.exports.deleteLessonFromClass = function(id, lesson_id, callback){ Class.update(
{'_id': id},
{ $unset: {lessons: {lesson_id: lesson_id}}},
callback
) }
Try the following query:
db.collection.update(
{ "_id" : <id> },
{ $pull : { "lessons" : { "lesson_id" : <lesson_id> } } }
);
This will find a document by <id> and remove its <lesson_id> from its lessons array.
Hope this helps.

Category hierarchy aggregation using mongodb and nodejs

My document structure is as follows:
{
"_id" : ObjectId("54d81827e4a4449d023b4e34"),
"cat_id" : 1,
"description" : "Refridgerator",
"image" : "refridgerator",
"parent" : null,
"slug" : "refridgerator"
}
{
"_id" : ObjectId("54dc38bce4a4449d023b4e58"),
"name" : "Ice Cream",
"description" : "Ice Cream",
"image" : "ice-cream.jpg",
"slug" : "ice-cream",
"parent" : "54d81827e4a4449d023b4e34"
}
{
"_id" : ObjectId("54dc3705e4a4449d023b4e56"),
"name" : "Chocolate",
"description" : "Chocolate",
"image" : "chocolate.jpg",
"slug" : "chocolate",
"parent" : "54d81827e4a4449d023b4e34"
}
I’m making a category hierarchy using mongodb and nodejs.
Now I wish to query for _id = ‘54d81827e4a4449d023b4e34’ (Refridgerator) and should get back all the child categories
How to achieve the above in nodejs?
Also, nodejs uses async call to the database, I’m unable to get the json structured with parent – child relations.
How would I do the async call for this?
You want the refridgerator and all the subcategories?
And async is also a problem?
I think you can use aggregation here.
Say you're looking for a category with _id variable which is an ObjectId of what you want, and it's subcategories.
db.yourCollection.aggregate({
// get stuff where you have the parent or subcats.
$match: {
$or: [
{_id: ObjectId("54de8b9f022ff38bbf5e0530")},
{parent: ObjectId("54de8b9f022ff38bbf5e0530")}
]
}
},
// reshape the data you'll need further on from each mached doc
{
$project: {
_id: false,
data: {
id: '$_id',
name: '$name'
// I guess you'll also want the `slug` and `image` here.
// but that's homework :)
},
parent: '$parent'
}
},
// now put a common _id so you can group them, and also put stuff into arrays
{
$project: {
id: {$literal: 'id'},
mainCategory: {
// if our parent is null, put our data.
// otherwise put null here.
$cond: [{$eq: [null, '$parent']}, {_id: '$data.id', name: '$data.name'}, undefined]
},
subcat: {
// here is the other way around.
$cond: [{$ne: [null, '$parent']}, {_id: '$data.id', name: '$data.name'}, null]
}
}
// that stage produces for each doc either a mainCat or subcat
// (and the other prop equals to null)
},
// finally, group the things so you can have them together
{
$group: {
_id: '$id',
// a bit hacky, but mongo will yield to it
mainCategory: {$max: '$mainCategory'},
subCategories: {
// this will, unfortunately, also add the `null` we have
// assigned to main category up there
$addToSet: '$subcat'
}
}
},
// so we get rid of the unwanted _id = 'id' and the null from subcats.
{
$project: {
_id: false,
mainCategory: 1,
subCategories: {
$setDifference: ['$subCategories', [null]]
}
}
})
Given this data set:
[{
"_id" : ObjectId("54de8b9f022ff38bbf5e0530"),
"name" : "Fridge",
"parent" : null
},
{
"_id" : ObjectId("54de8bba022ff38bbf5e0531"),
"name" : "choco",
"parent" : ObjectId("54de8b9f022ff38bbf5e0530")
},
{
"_id" : ObjectId("54de8bc8022ff38bbf5e0532"),
"name" : "apple",
"parent" : ObjectId("54de8b9f022ff38bbf5e0530")
}
I get this result:
{
"result" : [
{
"mainCategory" : {
"_id" : ObjectId("54de8b9f022ff38bbf5e0530"),
"name" : "Fridge"
},
"subCategories" : [
{
"_id" : ObjectId("54de8bc8022ff38bbf5e0532"),
"name" : "apple"
},
{
"_id" : ObjectId("54de8bba022ff38bbf5e0531"),
"name" : "choco"
}
]
}
],
"ok" : 1
}
As for async, typically you'd do something like this:
db.collection.aggregate(thePipeLineAbove, function(err, results) {
// handle err
if (err) {
// deal with it
} else {
console.log(results);
}
});
But that depends a bit on your MongoDB driver.
You could expand this even if you have deeper hierarchy structure.
This has nothing to do with NodeJS, it's your data structure that matters.
refer to my answer to this question, the first part is about how to implement it efficiently.

Resources