Mongodb aggregate with joins with multiple keys statement - mongodb-query

Actually i am not trying to match two collection's . I am looking for match the field with secondary collection. I'll explain my problem clearly:
this is my primary collection "bags".which contains
{
"_id" : ObjectId("568f43e08a9f71b70b22a694"),
"bagNo" : "HBBN/00001/16",
"category" : "Voluntary",
"regNo" : "DNR/00001/16",
"status": "Accepted"
},
{ "_id" : ObjectId("568f4645fa0758af0e3fef26"), "bagNo" :"HBBN/00002/16", "category" : "Voluntary", "regNo" : "DNR/00002/16", "status": "Rejected" },
{ "_id" : ObjectId("568f4645fa4546gygfef26"), "bagNo" : "HBBN/00003/16", "category" : "Voluntary", "regNo" : "DNR/00003/16", "status": "Accepted" }
now my join collection "donor" contains
{"donorType" : "H",
"regNo" : "DNR/00001/16",
"surName" : "pandey",
"firstName" : "rakesh"},
{"donorType" : "C", "regNo" : "DNR/00002/16", "surName" : "pandey", "firstName" : "rakesh" },
{"donorType" : "C", "regNo" : "DNR/00003/16", "surName" : "pandey", "firstName" : "rakesh" }
from these two collections i want to get the accepted bags data from bags collection which having 'donortype' as 'H' in donor collection.Please let me know if it is possible.explain with some example

To combine two collections, you could try to do it with $lookup in aggregation.
donor.aggregation([
// filter the `donortype` of `H`
{$match: {donortype: 'H'}},
// join with `bags` collection for the foreign key `regNo`, and put bags into `h_bags` result.
{$lookup: {
from: "bags",
localField: "regNo",
foreignField: "regNo",
as: "h_bags"
}},
// unwind the `h_bags` array
{$unwind: '$h_bags'},
// filter the status of bags is `Accepted`
{$match: {'h_bags.status': 'Accepted'}}
]);

Related

Problem requesting additional fields in REST2 api

I am using the RT::Extension::REST2 api (https://metacpan.org/pod/RT::Extension::REST2) for a project and i am having a problem requesting additional fields in some requests.
I need to make a TicketSQL query and for performance reasons i am trying to obtain all the information of a ticket with something like /REST/2.0/ticket/8?fields=Requestor and i get something like
"Requestor": [
{
"_url" : "http://<>/REST/2.0/user/example#example.com",
"id" : "example#example.com",
"type" : "user"
},
{
"_url" : "http://<>/REST/2.0/user/example#example.com",
"id" : "example#example.com",
"type" : "user"
}
]
Notice it is a List of dictionaries, so when i try to do /REST/2.0/ticket/8?fields[Requestor]=Name the field Name does not appear on the dictionaries inside the list.
So i am trying to get something like this:
"Requestor": [
{
"_url" : "http://<>/REST/2.0/user/example#example.com",
"id" : "example#example.com",
"type" : "user",
"Name" : "user20",
},
{
"_url" : "http://<>/REST/2.0/user/example#example.com",
"id" : "example#example.com",
"type" : "user",
"Name" : "user20",
}
]
Is there any way i can do this ?
Thank you for your help!

Remove Subdocument items with $pull

I'm trying to remove items from subdocuments using ExpressJS and Mongoose but it is only removing the first items, not the sub items.
So I want to remove "subitem 2" in the messages Array
This is the structure:
{
"_id" : ObjectId("5c4ee94b30ebd71cbed89a35"),
"title" : "Test",
"subitem" : [
{
"_id" : ObjectId("5c4ee95630ebd71cbed89a36"),
"title" : "Item 1",
"messages" : [
{
"_id" : ObjectId("5c4ee95f30ebd71cbed89a37"),
"type" : "single_article",
"date" : "Jan 28, 2019",
"title" : "subitem 1",
"text" : ""
}
]
},
{
"_id" : ObjectId("5c4ee96830ebd71cbed89a38"),
"title" : "item 2",
"messages" : [
{
"_id" : ObjectId("5c4ee96e30ebd71cbed89a39"),
"type" : "single_article",
"date" : "Jan 28, 2019",
"title" : "subitem 2",
"text" : ""
}
]
}
],
"__v" : 0
}
And this is the $pull method:
getController.deleteRec = function(req,res,collection){
var id = req.params.id;
console.log(id);
collection.updateOne({'subitem.messages._id': id}, {$pull: {'subitem.0.messages': {"_id": id}}}).
then(function(result){
console.log(result);
});
};
Now I know why it is only deleting the first item because I have "subitem.0.messages". How can I loop over this, so it can delete all items?
You can use $ as a wildcard index, removing all elements in the array matching your query like this:
{$pull: {'subitem.$.messages': {"_id": id}}}
if you want to remove multiple documents:
{$pull: {'subitem.$.messages': {"_id": {$in : [id, id2, id3...]}}}}

MongoDB Aggregate to Fill an Array Where Not In Results

Simplifying the case, I have the following collections:
db.emails.find()
{ "_id" : ObjectId("5b59db643fd217eb78b1eb6d"), "title" : "abc" }
{ "_id" : ObjectId("5b59db643fd217eb78b1eb6e"), "title" : "def" }
and
db.users.find()
{ "_id" : ObjectId("5b59dbab3fd217eb78b1eb70"), "name" : "john", "forwarded" : [ObjectId("5b59db643fd217eb78b1eb6d")] }
{ "_id" : ObjectId("5b59dbac3fd217eb78b1eb71"), "name" : "mary", "forwarded" : [ObjectId("5b59db643fd217eb78b1eb6e")] }
where that forwarded column means all the emails that have already been forwarded to that given user.
I need to create something like this:
{ "_id" : ObjectId("5b59dbab3fd217eb78b1eb70"), "name" : "john", "forwarded" : [ {_id: ObjectId("5b59db643fd217eb78b1eb6d"), title: "abc"}], "not_forwarded" : [ {_id: ObjectId("5b59db643fd217eb78b1eb6e"), title: "abc"}] }
{ "_id" : ObjectId("5b59dbac3fd217eb78b1eb71"), "name" : "mary", "forwarded" : [ { _id: ObjectId("5b59db643fd217eb78b1eb6e"), title: "def" }], "not_forwarded" : [ { _id: ObjectId("5b59db643fd217eb78b1eb6d"), title: "def" }] }
By using aggregate.
So far, I have been able to create the "forwarded" part mappings, but I'm still trying to create the "not_forwarded" mapping.
I'm too much of a noob in the noSQL world to make this simple "outer join".
As I said, for the "forwarded" mapping, it was easy. I created something like this:
db.users.aggregate([
{ $lookup: { from: "emails", localField: "forwarded", foreignField: "_id", as: "forwarded"}},
{ $project: { "email_ids._id": 0, "email_ids.tile": 0}}
]);
Now, I'm trying to add the "not_forwarded" part, by adding some $match function, where (I guess) the clause would be a $nin aggregate, to fill inside the "not_forwarded" array, all the not yet sent items.
...and that's where I'm miserably failing.
Or in much simpler terms, I'm trying to come up with a query that will render all the emails that haven't yet been forwarded to the users in the DB.
Up to this day, I had it by making javascript loops, first in the emails' recordset, then nested inside, looping through all the users. Then creating a new recordset with all the pending emails to be sent.
This is ugly and non performatic. I would very much like to take full advantage of this aggregate mechanism to get these results.

Postgres query to return rows where json in the json column contains array elements more than one

We are using Postgres DB , in that we have one table contains column of type JSON , format is like below
{
"name" : "XXX",
"id" : "123",
"course" :[
{
"name" : "java",
"tutor":"YYYY"
},
{
"name" : "python",
"tutor":"ZZZZ"
}
]
}
{
"name" : "XXX",
"id" : "123",
"course" :[
{
"name" : "java",
"tutor":"YYYY"
},
{
"name" : "python",
"tutor":"ZZZZ"
}
]
}
like this for example we have two rows , and in the json column we have each like above
i want to Postgre query , which will check the number of elements in the course array and if it is more than one , then only return that row
am not getting how to count the array elements from inside the json key
can any please suggest
why not just json_array_length?.. eg:
f=# with c(j) as (values('{
"name" : "XXX",
"id" : "123",
"course" :[
{
"name" : "java",
"tutor":"YYYY"
},
{
"name" : "python",
"tutor":"ZZZZ"
}
]
}'::json))
select json_array_length(j->'course') from c;
json_array_length
-------------------
2
(1 row)
so smth like
select * from table_name where json_array_length(j->'course') > 1

remove specific object from MongoDB collection

I'm trying to remove from MongoDB collection an object (not document) that meets specific value condition, in this case - "Accessible" : "null" - while keeping other instances of this objects. I tried db.collection.update({}, {$unset: { "Accessible":"null"}}, false, true) but it removed all objects with "Accessible" key.Thanks in advance
My MongoDB collection before update
{
"_id" : ObjectId("52e5f09e8f3d99e1046abccc"),
"Name" : "Skyline",
"Accessible" : "Y"
}
{
"_id" : ObjectId("52e5f09e8f3d99e1046abccd"),
"Name" : "Highland",
"Accessible" : "null"
}
Desired result:
{
"_id" : ObjectId("52e5f09e8f3d99e1046abccc"),
"Name" : "Skyline",
"Accessible" : "Y"
}
{
"_id" : ObjectId("52e5f09e8f3d99e1046abccd"),
"Name" : "Highland"
}
You need to first identify the documents you wish to update and then unset that specific field:
db.collection.update(
{"Accessible" : "null"},
{$unset: { "Accessible" : ""}},
{ multi: true }
)
Further documentation on $unset operator:
http://docs.mongodb.org/manual/reference/operator/update/unset/