How to save aggregation change? - linux

I am executing the following:
db.emails.aggregate(
[
{$addFields : {arr : {$objectToArray : "$$ROOT"}}},
{$project : { pass : {$slice : ["$arr.v", 1, 20 ] }}}
]
).pretty()
When I exit the session / shell, the changes are not saved.
Can someone please direct me on how to apply this modification to the entire collection and save it?

looks like continuation of How to merge multiple fields in a collection?
you can $out to new collection,check data,rename to old collection name dropping old data
db.emails.aggregate(
[
{$addFields : {arr : {$objectToArray : "$$ROOT"}}},
{$project : { pass : {$slice : ["$arr.v", 1, 20 ] }}},
{$out : "new_emails"} // out to new collection
]
).pretty()
db.new_emails.renameCollection('emails', true); // rename collection, true - dropTarget

Related

$add,$subtract aggregation-framework in mongodb

Hi i am mentioning the sample data
///collection - test////
{
"_id" : {
"date" : ISODate("2020-02-11T17:00:00Z"),
"userId" : ObjectId("5e43e5cdc11f750864f46820"),
"adminId" : ObjectId("5e43de778b57693cd46859eb")
},
"outstanding" : 212.39999999999998,
"totalBill" : 342.4,
"totalPayment" : 130
}
{
"_id" : {
"date" : ISODate("2020-02-11T17:00:00Z"),
"userId" : ObjectId("5e43e73169fe1e3fc07eb7c5"),
"adminId" : ObjectId("5e43de778b57693cd46859eb")
},
"outstanding" : 797.8399999999999,
"totalBill" : 797.8399999999999,
"totalPayment" : 0
}
I need to structure a query which does following things-
I need to calculate the actualOutstanding:[(totalBill+outstanding)-totalPayment],
I need to save this actualOutstanding in the same collection & in the same document according to {"_id" : {"date","userId", "adminId" }}
NOTE: userId is different in both the documents.
Introduced in Mongo version 4.2+ pipelined updates, meaning we can now use aggregate expressions to update documents.
db.collection.updateOne(
{
"adminId" : ObjectId("5e43de778b57693cd46859eb")
'_id."userId" : ObjectId("5e43e73169fe1e3fc07eb7c5"),
'_id.date': ISODate("2020-02-11T18:30:00Z"),
},
[
{ '$set': {
actualOutstanding: {
$subtract:[ {$add: ['$totalBill','$outstanding']},'$totalPayment']
}
} }
]);
For any other Mongo version you have to split it into 2 actions, first query and calculate then update the document with the calculation.

Saving aggregation results using $out, why does this not work?

I'm trying to save the aggregation changes to a collection using $out.
db.emails.aggregate(
[
{$addFields : {arr : {$objectToArray : "$$ROOT"}}},
{$project : { pass : {$slice : ["$arr.v", 1, 20 ] }}}
]
{
$out : "realEmails"
}
)
Why does this not work?
Here is the error that I receive:
[thread1] SyntaxError: missing ) after argument list #(shell):7:0
You have to put the out block inside the array.
db.emails.aggregate([
{$addFields : {arr : {$objectToArray : "$$ROOT"}}},
{$project : { pass : {$slice : ["$arr.v", 1, 20 ] }}},
{$out : "realEmails"}
])

MongoDB query with embedded document in array (3 levels)

I had this data on my MongoDB database and I would like to get only the second array about blades.
{
"_id" : ObjectId("..."),
"name" : "Westereems",
"country" : "Netherlands",
"turbines" : [
{
"turbine_id" : ObjectId("..."),
"blades" : [
{
"blade_id" : ObjectId("..."),
"position" : 2,
"size" : 50,
}
]
}
]
}
I only want one return with blade_id, position and size. I tried this query and I didn't have the expectable result:
db.collection("windfarms").find({"turbines.blades.blade_id" : ObjectId("...")}, {"turbines.blades.$" : 1, "_id" : 0})
Regards,
You can use this query, it's not an optimal query for large array's items but if you have only above items then you can use it.
you can also go with aggregation to make it more optimal.
db.collection("windfarms").find({"turbines.blades.blade_id" : ObjectId("...")}, {"turbines.blades.blade_id":1,"turbines.blades.position":1,"turbines.blades.size":1,"_id":0})

finding the parent document id based on the sub document _id of array field

Hyy , I have a collection where comments related to the blog are stored in multiple document as shown below.
[
{
"_id" : ObjectId("565f0f5d77f0c7bd11bbadd8"),
"blog_id" : ObjectId("56587befdb7224110f007233"),
"comments" : [
{
"user_id" : ObjectId("562fa014888806820e21e0df"),
"user_full_name" : "Niroj Paudel",
"comment" : "pradip is bhole baba",
"_id" : ObjectId("565f0f5d77f0c7bd11bbadd9"),
"dt" : ISODate("2015-12-02T15:33:49.578Z")
},
{
"user_id" : ObjectId("562fa014888806820e21e0df"),
"user_full_name" : "Niroj Paudel",
"comment" : "honkog pokhara... he he ha ha",
"_id" : ObjectId("565f1034fd07cbfc1129db0b"),
"dt" : ISODate("2015-12-02T15:37:24.581Z")
}
],
"record_count" : 2,
"__v" : 0
}
{
"_id" : ObjectId("565efa37635f09900d21a339"),
"blog_id" : ObjectId("56587befdb7224110f007233"),
"comments" : [
{
"user_id" : ObjectId("562fa014888806820e21e0df"),
"user_full_name" : "Niroj Paudel",
"comment" : "wat a nice car wow",
"_id" : ObjectId("565efa37635f09900d21a33a"),
"dt" : ISODate("2015-12-02T14:03:35.289Z")
},
{
"user_id" : ObjectId("562fa014888806820e21e0df"),
"user_full_name" : "Niroj Paudel",
"comment" : "love is life budikhola ma dives",
"_id" : ObjectId("565efa76635f09900d21a33b"),
"dt" : ISODate("2015-12-02T14:04:38.661Z")
},
{
"user_id" : ObjectId("562fa014888806820e21e0df"),
"user_full_name" : "Niroj Paudel",
"comment" : "bholi ajaya ko bihe",
"_id" : ObjectId("565efaa0635f09900d21a33c"),
"dt" : ISODate("2015-12-02T14:05:20.847Z")
},
{
"user_id" : ObjectId("562fa014888806820e21e0df"),
"user_full_name" : "Niroj Paudel",
"comment" : "manish is nice",
"_id" : ObjectId("565efb17635f09900d21a33d"),
"dt" : ISODate("2015-12-02T14:07:19.704Z")
},
{
"user_id" : ObjectId("562fa014888806820e21e0df"),
"user_full_name" : "Niroj Paudel",
"comment" : "niroj is cool",
"_id" : ObjectId("565efd53c22dddc80e8f461c"),
"dt" : ISODate("2015-12-02T14:16:51.730Z")
},
{
"user_id" : ObjectId("562fa014888806820e21e0df"),
"user_full_name" : "Niroj Paudel",
"comment" : "ramesh is cool",
"_id" : ObjectId("565f0d376d82e24c11f6c0d1"),
"dt" : ISODate("2015-12-02T15:24:39.010Z")
}
],
"record_count" : 6,
"__v" : 0
}
]
Suppose user wants to update his comment; for this I would have the comments _id now my problem is that how can I detect in which document the comment exist based of the comment _id value of comments array field.
suppose I have a comment "_id" : "565f0f5d77f0c7bd11bbadd9" (first element of first document)
then the result should give the parent document _id:"565f0f5d77f0c7bd11bbadd8" (first document id)
How can I do this..
Thank you in advance
if possible, then please update your schema.
Suppose you have collection of Blog. Then your code will be :
Blog.find({'comments._id' : '565f0f5d77f0c7bd11bbadd9'}).exec(function(err,blog){
if(!err && blog){
console.log("Blog id :"+blog._id);
}
else{
console.log("Dont get your blog");
}
});
if your comments are directly stored on the blog document you could go with an aggregate method to collect the comment across all documents. note that this seems to work when you don't have any object references to be populated.
asuming all documents are based on a blog Schema and that you wish to recieve the id of the comment:
Blog.aggregate(
[{'$match':{'comments':{'$elemMatch:{'_id':'565f0f5d77f0c7bd11bbadd9'}}}},
{'$project':{comments:'$_id', user_id:1}},
{'$unwind':'$comments'}
{'$group':{_id:'$comments'}}
]).exec(function(err, results){
if(results){
console.log(results);
}
});
I hope this is somewhat what you're looking for, you might find the following read usefull
elementMatch and aggregation from the mongoDB docs.
cheers!
The site recommended this old question to me as being Related to another I was looking at. Looks like a sufficient answer wasn't ever given, so I'll provide it for any future readers.
The requested behavior here is very straightforward to achieve with a basic find() query:
db.collection.find(
{ "comments._id": ObjectId("565f0f5d77f0c7bd11bbadd9") },
{ _id: 1 }
)
Here we are filtering the documents based on the values of the _id fields embedded in the comments array. Then for the matching document(s) we are applying a projection to just retrieve the _id field of the "parent document" (e.g. the document that was matched). If the _ids for the comments are unique then there will only ever be a maximum of a single matching document. Sample playground demonstration is here.
A more complicated aggregation would have only been necessary here if the intent was to always provide the _id value of the first document associated with a given blog_id but that does not appear to be the case here.

How can i retrieve a subrecord from mongo DB

I have a db that looks like this :
{
"_id" : ObjectId("50525e55467f67da3f8baf06"),
"client" : "client1"
}
{
"_id" : ObjectId("505262f0deed32a758410b1c"),
"client" : "client2"
}
{
"_id" : ObjectId("5052fe0a37083fd981616589"),
"client" : "client3",
"products" : [
{"name" : "product1"},
{"name" : "product2"}
]
}
How can i retrieve the product list of client3 without retrieving the client3 record ?
The output should look like this :
[
{"name" : "product1"},
{"name" : "product2"}
]
I don't think you can completely exclude the client3 record as the products are part of this record, but you can select just the products field like this:
db.<dbname>.find({ 'client' : 'client3' }, { 'products' : 1, '_id' : 0 })
Also - if you want to get just the matching subrecord - see here
http://docs.mongodb.org/manual/reference/operator/projection/positional/
you use the $ operator in the project portion of find to specify the n'th subrecord where that is the first to match your query.

Resources