Kevin.a
Kevin.a

Reputation: 4296

Mongo find query only returns one result

Hello I have the following data structure :

[
  {
    "name": "a name",
    "project": [
      {
        companyName: "a name",
        contactPerson: [
          {
            work_email: "[email protected]"
          }
        ]
      },
      {
        companyName: "a name1",
        contactPerson: [
          {
            work_email: "[email protected]"
          }
        ]
      },
      {
        companyName: "a name2",
        contactPerson: [
          {
            work_email: "[email protected]"
          }
        ]
      },
      {
        companyName: "a name3",
        contactPerson: [
          {
            work_email: "[email protected]"
          }
        ]
      },
      
    ]
  }
]

With this query i want to find all projects that have the email [email protected] :

db.collection.find({
  "project.contactPerson.work_email": "[email protected]"
},
{
  "project.$": 1
})

It only returns the first result it finds and then it just stops. but in my data i have two projects with that email and i want to find both. here's a playground you can use to further help me if you can. Thanks in advance and much appreciated : https://mongoplayground.net/p/4Mpp7kHi98u

Upvotes: 1

Views: 838

Answers (3)

Mallik
Mallik

Reputation: 334

//step1(problem statement related find):, find shows all projects even one of the array element of contact is matched, use an aggregate function to display specific email ids

> db.test3.find({    "project.contact.email": "[email protected]" }).pretty();
{
        "_id" : ObjectId("5f43fdc153e34ac6967fe8ce"),
        "name" : "Pega Contractors",
        "project" : [
                {
                        "pname" : "pname1",
                        "contact" : [
                                {
                                        "email" : "[email protected]"
                                }
                        ]
                },
                {
                        "pname" : "pname2",
                        "contact" : [
                                {
                                        "email" : "[email protected]"
                                }
                        ]
                },
                {
                        "pname" : "pname3",
                        "contact" : [
                                {
                                        "email" : "[email protected]"
                                }
                        ]
                }
        ]
}
--
//aggregate option:

//Step1: data preparation
> db.test3.find().pretty();
{
        "_id" : ObjectId("5f43fdc153e34ac6967fe8ce"),
        "name" : "Pega Contractors",
        "project" : [
                {
                        "pname" : "pname1",
                        "contact" : [
                                {
                                        "email" : "[email protected]"
                                }
                        ]
                },
                {
                        "pname" : "pname2",
                        "contact" : [
                                {
                                        "email" : "[email protected]"
                                }
                        ]
                },
                {
                        "pname" : "pname3",
                        "contact" : [
                                {
                                        "email" : "[email protected]"
                                }
                        ]
                }
        ]
}
>

//step2: aggregate and unwind project for the next step pipeline input
> db.test3.aggregate([ {$unwind: "$project"}]);
{ "_id" : ObjectId("5f43fdc153e34ac6967fe8ce"), "name" : "Pega Contractors", "project" : { "pname" : "pname1", "contact" : [ { "email" : "[email protected]" } ] } }
{ "_id" : ObjectId("5f43fdc153e34ac6967fe8ce"), "name" : "Pega Contractors", "project" : { "pname" : "pname2", "contact" : [ { "email" : "[email protected]" } ] } }
{ "_id" : ObjectId("5f43fdc153e34ac6967fe8ce"), "name" : "Pega Contractors", "project" : { "pname" : "pname3", "contact" : [ { "email" : "[email protected]" } ] } }

//step3: Desired outcome, i.e display data specific to email
> db.test3.aggregate([
...    {$unwind: "$project"},
...    {$match: {"project.contact.email":"[email protected]"}}
...    ]);
{ "_id" : ObjectId("5f43fdc153e34ac6967fe8ce"), "name" : "Pega Contractors", "project" : { "pname" : "pname1", "contact" : [ { "email" : "[email protected]" } ] } }
{ "_id" : ObjectId("5f43fdc153e34ac6967fe8ce"), "name" : "Pega Contractors", "project" : { "pname" : "pname3", "contact" : [ { "email" : "[email protected]" } ] } }
> db.test3.aggregate([    {$unwind: "$project"},    {$match: {"project.contact.email":"[email protected]"}}    ]);
> db.test3.aggregate([    {$unwind: "$project"},    {$match: {"project.contact.email":"[email protected]"}}    ]);
{ "_id" : ObjectId("5f43fdc153e34ac6967fe8ce"), "name" : "Pega Contractors", "project" : { "pname" : "pname2", "contact" : [ { "email" : "[email protected]" } ] } }
>

Upvotes: 0

Visakh Vijayan
Visakh Vijayan

Reputation: 718

db.collection.aggregate([
  {
    $unwind: "$project"
  },
  {
    $match: {
      "project.contactPerson.work_email": "[email protected]"
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "name": {
        "$first": "$name"
      },
      "project": {
        "$push": {
          "companyName": "$project.companyName",
          "contactPersion": "$project.contactPerson"
        }
      }
    }
  }
])

Upvotes: 1

varman
varman

Reputation: 8894

The positional $ operator limits the contents of an to return either:

  1. The first element that matches the query condition on the array.
  2. The first element if no query condition is specified for the array (Starting in MongoDB 4.4). Ref

You can do something like following,

[
  {
    "$unwind": "$project"
  },
  {
    $addFields: {
      "project.contactPerson": {
        $filter: {
          input: "$project.contactPerson",
          cond: {
            $eq: [
              "$$this.work_email",
              "[email protected]"
            ]
          }
        }
      }
    }
  },
  {
    $match: {
      $expr: {
        $ne: [
          "$project.contactPerson",
          []
        ]
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      name: {
        $first: "$name"
      },
      project: {
        "$addToSet": "$project"
      }
    }
  }
]

Working Mongo playground

Upvotes: 1

Related Questions