1

I have data like this:

{
    "global": {
        "summaryNotificationSchedule": {
            "weekDay": ["wednesday"]
        }
    },
    "userEmail": "[email protected]",
    "environments": [
        {
            "userPreference": {
                "summaryNotificationSchedule": {
                    "weekDay": ["friday"]
                }
            },
            "envId": "u1"
        },
        {
            "userPreference": {
                "summaryNotificationSchedule": {
                    "weekDay": ["tuesday"],
                }
            },
            "envId": "u2"
        }
    ]
}

and I need to get userPreference object from environments array based on envId.

Tried this but its returning complete array but I need to return object inside the array i.e. userPreference

const envData = await preferencesModel.findOne({ userEmail, "environments.envId": envId }, { 'environments.$.envId': envId }).lean();

2 Answers 2

1

You can use positional operator. But be ware to use postional operator in projection

db.collection.find({
  "environments.envId": "u2"
},
{
  "environments.userPreference.$": 1
})

Working Mongo playground

Update 1,

The output is As you expected

[
  {
    $project: {
      environments: {
        $filter: {
          input: "$environments",
          cond: {
            $eq: [
              "$$this.envId",
              "u1"
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      userPreference: {
        $ifNull: [
          {
            $arrayElemAt: [
              "$environments.userPreference",
              0
            ]
          },
          {}
        ]
      }
    }
  }
]

Working Mongo playground

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

4 Comments

await preferencesModel.findOne({ userEmail, "environments.envId": envId }, { "environments.userPreference.$": 1 }) it still returns the array
u need the summaryNotificationSchedule?
yes but I need to return only object: { "userPreference": { "summaryNotificationSchedule": { "weekDay": ["tuesday"] } }
Does that help you?
1

give the following a go:

find query:

db.collection.findOne(
    {
        userEmail: "[email protected]",
    },
    {
        environments: {
            $elemMatch: {
                envId: "u1"
            }
        }
    }
)

aggregation pipeline:

db.collection.aggregate([
    {
        $match: {
            userEmail: "[email protected]"
        }
    },
    {
        $set: {
            environments: {
                $first: {
                    $filter: {
                        input: "$environments",
                        cond: { $eq: ["$$this.envId", "u1"] }
                    }
                }

            }
        }
    },
    {
        $replaceWith: "$environments.userPreference"
    }
])

Comments

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.