neonguru
neonguru

Reputation: 759

How to fix a MongoDB aggregate $project $filter

I have data that looks like this:

{
  "_id" : 1,
  "data" : [
    {
      "id" : 1,
      "one" : [
        {"user" : 2, "two" : 2},
        {"user" : 1, "two" : 3}
      ]
    }
  ]
}
{
  "_id" : 2,
  "data" : [
    {
      "id" : 2,
      "one" : [
        {"user" : 2, "two" : 2},
        {"user" : 1, "two" : 3}
      ]
    }
  ]
}

And I want to filter in an aggregate (since the data above is from previous stages) so that the one array is filtered to only show one array items where the user is equal to the _id.

The following returns empty one arrays, how to I get the filter to fill in the one array as I expect?

db.parks.aggregate([{$project: {_id: 1, 'data.id': 1, 'data.one':
{$filter: {
  input: '$data.one',
  as: 'un',
  cond: {$eq: ['$$un.user', '$_id']}}
}}}]).pretty()

Which gives:

{ "_id" : 1, "data" : [ { "id" : 1, "one" : [ ] } ] }
{ "_id" : 2, "data" : [ { "id" : 2, "one" : [ ] } ] }

Replacing '$_id' with '$$un.user' shows all data.one items as expected, so it looks like the problem is in the $eq statement.

How to I get the filter to show the one array as I expect?

Upvotes: 1

Views: 499

Answers (1)

Ashh
Ashh

Reputation: 46441

You can use below aggregation

db.collection.aggregate([
  { "$project": {
    "data": {
      "$filter": {
        "input": {
          "$map": {
            "input": "$data",
            "in": {
              "id": "$$this.id",
              "one": {
                "$filter": {
                  "input": "$$this.one",
                  "as": "on",
                  "cond": { "$eq": ["$$on.user", "$_id"] }
                }
              }
            }
          }
        },
        "as": "d",
        "cond": { "$eq": ["$$d.id", "$_id"] }
      }
    }
  }}
])

MongoPlayground

Upvotes: 1

Related Questions