Reputation: 925
I'm new in MongoBb.Tried but not able to write a single query that will give matched number of users from two different brands.
I have a collection called users and data is like:
{
"_id" : ObjectId("574c09aaa49544e70a694940"),
"phone_number" : "919876543210",
"name" : "Jack",
"brand" : "A"
},
{
"_id" : ObjectId("574c09aaa49544e70a694840"),
"phone_number" : "910123456789",
"name" : "John",
"brand" : "B"
},
{
"_id" : ObjectId("574c09aaa49544e70a695040"),
"phone_number" : "919876543210",
"name" : "Jack",
"brand" : "B"
}
My problem is I want to find those phone_number
that is present in both brands brand:A
and brand:B
.
I have written below db script that is working fine. But I want a single mongo query that give me a same result.
conn = new Mongo();
db = conn.getDB("users-db");
var phoneNumberList = [];
var query1 = {
brand: "A"
};
db.users.find(query1).forEach(function(obj) {
if (obj.phone_number) {
print(obj.phone_number);
phoneNumberList.push(obj.phone_number);
}
})
print("Size of phoneNumberList", phoneNumberList.length);
var query2 = {
brand: "B",
phone_number: { $in: phoneNumberList }
};
var matchedUser = db.users.find(query2).count();
print("Total Matched Users", matchedUser);
Upvotes: 0
Views: 613
Reputation: 61225
You are using the wrong method. You need to use the .aggregate()
method.
db.users.aggregate(
[
{ "$match": { "brand": { "$in": [ "A", "B" ] } } },
{ "$group": {
"_id": "$phone_number",
"brand": { "$addToSet": "$brand" }
}},
{ "$match": { "brand": { "$all": ["A", "B"] } } },
{ "$group": { "_id": null, "phone_numbers": { "$push": "$_id" }, "count": { "$sum": 1 } } }
]
)
The $match
operator selects only those documents that satisfy a given condition. The condition here is $in
which returns true if the "brand" is "A" or "B".
You then $group
by "phone_number" and use the $addToSet
accumulator operator to return an array of distinct "brand" for the group.
You then need another $match
to select only those documents that match your criteria using the $all
query operator.
Finally, you add another $group
stage to the pipeline and use the $push
accumulator operator to return an array of "phone_number" and $sum
to return the number of items in the array.
Upvotes: 2