1

I'm joining a document using aggregation in Mongo 3.6 and filtering results based on the elements inside one of the arrays. This is working ok except I want to filter out results where the filtered array is empty.

deployment_machine document:

{
  "_id": 1,
  "name": "Test Machine",
  "machine_status": 10, 
  "active": true
}

machine_status document:

{
  "_id": 10,
  "breakdown": [
    {
      "status_name": "Rollout",
      "state": "complete"
    },
    {
      "status_name": "Deploying",
      "state": "complete"
    }
  ]
}

The object I'm using in the python MongoEngine being passed to the aggregate function:

pipeline = [
    {'$lookup':
        {
            'from': 'deployment_machine',
            'let': {'status_id': '$_id'},
            'pipeline': [
                {'$match': {
                        '$expr': {'$eq': ['$system_status', '$$status_id']},
                        'active': True
                        },
                }
            ],
            'as': 'result',

        },
    },
    {'$project': {
        'breakdown': {'$filter': {
            'input': '$breakdown',
            'as': 'breakdown',
            'cond': {'$eq': ['$$breakdown.status_name', 'Rollout']}            
        }}
    }},
]

result = list(MachineStatus.objects.aggregate(*pipeline))

The result looks like this:

[
  {"_id": 1,"name": "Test Machine","machine_status": 10, "active": true, "breakdown": [{"status_name": "Rollout", "state": "complete"}]},
  {"_id": 2,"name": "Another Machine","machine_status": 11, "active": true, "breakdown": []}
]

I want to remove the result where breakdown is an empty array. Should I use a final match condition or can I do this in the project?

James MV
  • 8,569
  • 17
  • 65
  • 96
  • Final match condition – Alex Blex Apr 15 '20 at 08:00
  • I don't think you can do that in `$project`. IMO `$project` is used to mutate existing attributes or add new inside a document object. For your use case if I understand it correctly you want your document to be not in the final list if `breakdown` is empty. To achieve this you need a `$match` condition. – tirthbal Apr 15 '20 at 08:01
  • 1
    Add `{$match:{"breakdown.0":{$exists:true}}}` – Valijon Apr 15 '20 at 08:18

0 Answers0