0

My goal is to:

  1. Get all the documents with status=true.
  2. And return only objects with active=true in the life array.

Below is what my MongoDB documents look like:

{
    "name": "justine",
    "life" : [ 
        {
            "status" : true,
            "service" : [ 
                {
                    "partner" : "pat 1",
                    "active" : true,
                }, 
                {
                    "partner" : "pat 2",
                    "active" : false
                }
        }
    ]
},
{
    "name": "okumu",
    "life" : [ 
        {
            "status" : true,
            "service" : [ 
                {
                    "partner" : "pat 1",
                    "active" : true,
                }, 
                {
                    "partner" : "pat 2",
                    "active" : true
                }
        }
    ]
}

Expected output:

{
    "name": "justine",
    "life" : [ 
        {
            "status" : true,
            "service" : [ 
                {
                    "partner" : "pat 1",
                    "active" : true,
                }
        }
    ]
},
{
    "name": "okumu",
    "life" : [ 
        {
            "status" : true,
            "service" : [ 
                {
                    "partner" : "pat 1",
                    "active" : true,
                }, 
                {
                    "partner" : "pat 2",
                    "active" : true
                }
        }
    ]
}

This is what I did:

await Users.find({ life: { $elemMatch: { status: true, life: { $elemMatch: { active: false } } } }});

This is working well for the first condition, in case the second condition is not met, the entire object is not returned, however, if it's met, even the active=false objects are returned.

I'll be grateful if you can help me out, am not a MongoDB expert.

1 Answer 1

1

I think it is complex (possible not doable) with the .find() query.

You should use .aggregate() query.

  1. $match - Filter document with life.status is true.

  2. $project -

    2.1 $filter - Filter the document with status is true in life array document.

    2.1.1 $map - Merge the life document with the Result 2.1.1.1.

    2.1.1.1 $filter - The inner $filter operator to filter the document with active is true for service document in service array.

db.collection.aggregate([
  {
    $match: {
      "life.status": true
    }
  },
  {
    $project: {
      name: 1,
      life: {
        "$filter": {
          "input": {
            "$map": {
              "input": "$life",
              "in": {
                "$mergeObjects": [
                  "$$this",
                  {
                    "service": {
                      "$filter": {
                        "input": "$$this.service",
                        "as": "service",
                        "cond": {
                          $eq: [
                            "$$service.active",
                            true
                          ]
                        }
                      }
                    }
                  }
                ]
              }
            }
          },
          as: "life",
          "cond": {
            $eq: [
              "$$life.status",
              true
            ]
          }
        }
      }
    }
  }
])

Sample Mongo Playground

Sign up to request clarification or add additional context in comments.

3 Comments

I still wonder why your profile photo looks like an error file. Maybe it's bug from SO ?
Haha, my profile was linked with Facebook. And due to the Facebook account no longer being accessible, it shows a broken file.
Oh okay, now I get it ! Maybe SO should stored the photo in it's own database instead of stored only the link. I like your answer and I up vote it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.