How to group all documents matching for multiple fields mongodb - mongodb

I'm new to MongoDB!
I need to extract all documents having the same Address, type, and id only. There will be only a single address in addresses. Others attributes can have different values. see below Test doc for example:
{
"Id" : "123",
"type" : "T1",
"addresses" : [
{
"address" : {
"line1" : "line 1 ...",
"line2" : "line 2...",
"state" : "state1...",
"city" : "city1...",
"zip" : "123456"
}
}
],
"email" : "test1#gmail.com",
"salary" : ""
}
For Example I've below documents, first value is type, second is id, third is address, fourth is email and so on:
doc1 - t1 1 address1 email1 ...
doc2 - t1 2 address2 email2 ...
doc3 - t1 1 address1 email3 ...
doc4 - t1 1 address1 email4 ...
doc5 - t1 2 address2 email5 ...
doc6 - t1 1 address1 email6 ...
outcome: [ [doc1, doc3, doc4, doc6], [doc2, doc5] ]
Here doc1, doc3, doc4, doc6 having the same id, type, and address. And doc2, doc5 having the same id, type, and address.
Could anyone please suggest how to achieve this in MongoDB?

After reading the Mongo aggregation framework and some R&D, I was able to achieve this using below approach:
db.getCollection('test_collection').aggregate([
{
$group: {
_id: { type: "$type", id:"$Id", line1: "$addresses.0.address.line1" ... },
docGroups: { $addToSet: "$$ROOT" }
}
}
]);

Related

mongodb how to display Null or none for a field instead of it being blank

The query below will show me the names of people and all their details. Some have addresses, some have not. It shows the addresses where they exist. What do I use if I wanted to show "addresses: "none" " where there are none given? I am also trying to sort by name.
db.test.find({name:{$exists:true}}, {_id:0}, {$sort:{"name":1}})
So far I can select the ones which have names, hide the _id column from view and sort by name. All the addresses (where they exist) are given. It is the "addresses: none" I am finding tricky.
Any pointers? Thank you.
test collection with the following documents
{"_id" : 1, "name" : "Thyame", "address": "Kapan" },
{"_id" : 2, "name" : "Diple", "address": null },
{"_id" : 3, "name" : "Sid" }
and Query is
db.test.aggregate
(
[
{
$project: {
address: { $ifNull: [ "$address", "Null" ] }
}
}
]
);

MongoDB $group aggregation

I have collection like this
OrgName EmpId Domain Date
Google 12345 ABC 2017/01/01
Google 12345 XYZ 2017/02/01
Google 67890 ABC 2017/03/01
Google 45678 ABC 2017/03/02
Yahoo 69875 HGF 2017/03/02
Google 45678 XYZ 2017/03/03
Google 45678 XYZ 2017/03/03
Google 12345 XYZ 2017/03/03
Google 12345 ABC 2017/03/04
Google 12345 ABC 2017/04/05
I need to fetch which employee having the max "Domain" count and must be in both "ABC" and "XYZ" domain GROUPBY OrgName wise.
I am using below query:
db.Collection1.aggregate([{ "$match" : { "$or" : [ { "Domain": "ABC"},{ "Domain": "XYZ"}]}},
{
$group :{ "_id": {"OrgName" : "$OrgName", "EmpId" : "$EmpId",
"Domain" : "$Domain"},
            count:{ $sum : 1 },
"participantData" : { "$push" : { "EmpId" : "$EmpId" , "Domain" : "$Domain"}}}},
    {$sort:{"count":-1}},
     {$limit: 10}
],{ allowDiskUse: true })
In above example, am expecting result : employee_id=12345 present in both "ABC" and "XYZ" Domain count is 5 (i.e., 12345.ABC = 3 and 12345.XYZ=2).
You can try below query.
The below query $group by OrgName, EmpId followed by $match to filter documents where participant array contains both 'ABC' & 'XYZ` value.
$sort the filtered data by count and output first 10 values.
db.collection.aggregate([
{"$match":{"$or":[{"Domain":"ABC"},{"Domain":"XYZ"}]}},
{"$group":{
"_id":{"OrgName":"$OrgName","EmpId":"$EmpId"},
"count":{"$sum":1},
"participantData":{"$push":{"EmpId":"$EmpId","Domain":"$Domain"}}
}},
{"$match":{"participantData.Domain":{"$all":["ABC","XYZ"]}}},
{"$sort":{"count":-1}},
{"$limit":10}
])

MongoDB : Sort documents based on an object within an array

I have a collection which has a sample object as follows :
{
name : 'Sachin Tendulkar',
followers : {
location : {
countries : [{
name : 'India',
count : 12345
}, {
name : 'Pakistan',
count : 12345
},{
name : 'Australia',
count : 12345
}],
cities : [{
name : 'Mumbai',
count : 12345
},{
name : 'Karachi',
count : 12345
},{
name : 'Melborne',
count : 12345
}]
states : [{
name : 'Maharastra',
count : 12345
},{
name : 'Balochistan',
count : 12345
},{
name : 'Sydney',
count : 12345
}]
}
}
}
I wish to sort all the documents based on the city count. For example,
Sort all documents according to a specific city i.e. Mumbai's count
Can you help me build a query for sorting document as per the conditions mentioned above ?
I think this will be the query:
db.collection_name.aggregate([
{$unwind:"$followers.location.cities"},
{$match:{followers.location.cities.name:"Mumbai"},
{$sort:{"followers.location.cities.count":1}}
])

Find the documents in mongoose whose array fields exactly match

I'm using Mongoose and have a schema like this:
var chat = new mongoose.Schema({
chatId : String,
members : [{
id : String,
name : String
}]
});
Suppose I have two chat document like this
{
chatId : 'Edcjjb',
members : [
{
id : 'a1',
name : 'aaa'
},
{
id : 'b1',
name : 'bbb'
}
]
}
{
chatId : 'Fxcjjb',
members : [
{
id : 'a1',
name : 'aaa'
},
{
id : 'b1',
name : 'bbb'
},
{
id : 'c1',
name : 'ccc'
}
]
}
I want to find all those documents which have only specfied members Id.
For example, if I specify a1 and b1
then only the first document should be retrieved as the second document contains id c1 as well.
And if I specifiy a1,b1,c1
then only second document should be specified.
Please tell me how to do this in mongoose
You can specify a clause on the array size, like
{ members : { $size : 2 } } in your first example and
{ members : { $size : 3 } } in the second one.
Can that work for you?
EDIT: I should also mention that the other part of the query should be
{ "members.id": { $all: [ "a1" , "b1" ] } }
and, for the second example,
{ "members.id": { $all: [ "a1" , "b1", "c1" ] } }

mongodb ORing and ANDing query

I am using mongoDB database. in which I have collection in below format.
{ name : name1 , area: a , country : c}
{ name : name2 , area: b , country : c}
{ name : name3 , area: a1 , country : c1}
{ name : name4 , area: b1 , country : c1}
i want query like
select * from coll where (country =c and area =a) or (country = c1 and area = b1)
in mongodb query.
I have read many document but not found suitable answer.
So if any one knows please reply.
Thanks
By default, all elements in a mongodb query use the and operator. You can specify an or operator using the { "$or": [ ... ] } construct, as described in the documentation.
Your query will be :
{ "$or": [ { "country": "c", "area": "a" }, { "country": "c1", "area": "b1" } ] }