6

I have a mongodb collection which contains objects which have multiple properties (possibly a lot). One of this is an array of another object type, and this type has a boolean property StateChanged.

I want to make a query returning all the records from this collection, and filter the array to only get documents with StateChanged = true.

Here is what I already did:

db.getCollection('Cycles').aggregate([
    {
        $project: {
            _id: 0,
            // Here I could add Field1: 1, Field2: 1,...
            'Subcycles' : {
                $filter : {
                    input: '$Subcycles',
                    as : 'sub',
                    cond: { $eq: ['$$sub.StateChanged',true]}
                }
            }
        }
    }
])

However this only brings me the "Subcycles" collection. What I want is to include other fields in the root document.

I could specify them manually in the projection (like Field1: 1, Field2: 1,...), but as there can be a lot of fields, I was wondering if there exists a way to bring them all automatically.

Thanks in advance !

Ashh
  • 44,693
  • 14
  • 105
  • 132
Shimrod
  • 3,115
  • 2
  • 36
  • 56

2 Answers2

4

You can use $addFields instead of $project. It will automatically replace the new field with the existing field.

db.getCollection("Cycles").aggregate([
  { "$addFields": {
    "Subcycles": {
      "$filter": {
        "input": "$Subcycles",
        "as": "sub",
        "cond": { "$eq": ["$$sub.StateChanged", true] }
      }
    }
  }},
  { "$project" : { "_id": 0 }}
])
Ashh
  • 44,693
  • 14
  • 105
  • 132
2

You can use $addFields and then use $project to exclude _id field:

db.getCollection('Cycles').aggregate([
    {
        $addFields: {
            'Subcycles' : {
                $filter : {
                    input: '$Subcycles',
                    as : 'sub',
                    cond: { $eq: ['$$sub.StateChanged',true]}
                }
            }
        }
    },
    {
       $project: {
          _id: 0
       }
    }
])
mickl
  • 48,568
  • 9
  • 60
  • 89