imSonuGupta
imSonuGupta

Reputation: 925

How to find matched number of documents in same collection based on some fields?

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

Answers (1)

Sede
Sede

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

Related Questions