2

I have a simple document that stores arrays of objects for a user, and I am looking to get a sum of these arrays and a total of all; the challenge is that some documents are missing fields that other documents have, and this causes my aggregate query to fail.

Document looks like this.

{
  name: '',
  type: '',
  cars: [],
  boats: [],
  planes: []
}

Some people do not have boats or planes...and those documents might look like

{
  name: '',
  type: '',
  cars: []
}

So when I run my aggregate

[
  {
    '$match': {
      'type': 'big_spender'
    }
  }, {
    '$project': {
      'name': '$name', 
      'cars': {
        '$size': '$cars'
      }, 
      'boats': {
        '$size': '$boats'
      }, 
      'planes': {
        '$size': '$planes'
      }
    }
  }, {
    '$addFields': {
      'total_vehicles': {
        '$add': [
          '$cars', '$boats', '$planes'
        ]
      }
    }
  }
]

I get the error: "The argument to $size must be an array, but was of type: missing"

I am pretty sure I can use $exists to avoid this problem, and return a 0, but I have no idea what that syntax might look like.

I need to return a 0 for arrays that don't exist so when i add them for totals, I get a correct total and no errors.

Any help appreciated.

j-p
  • 3,698
  • 9
  • 50
  • 93
  • 1
    The title of the duplicate question used to be the error message returned when you referenced an array that was not there. The wording of the error message has in fact changed, as you have seen. Updating the title to make it easier to find. – Neil Lunn Apr 02 '19 at 05:56
  • Thx Neil - that will def help in future. – j-p Apr 02 '19 at 07:22

1 Answers1

6

Use $ifNull aggregation operator. It will replace the field with blank array if it does not exists.

[
  { '$match': { 'type': 'big_spender' }},
  { '$project': {
    'name': '$name', 
    'cars': { '$size': '$cars' }, 
    'boats': { '$size': { '$ifNull': ['$boats', []] }}, 
    'planes': { '$size': { '$ifNull': ['$planes', []] }}
  }},
  { '$addFields': {
    'total_vehicles': {
      '$add': [
        '$cars', '$boats', '$planes'
      ]
    }
  }}
]
Ashh
  • 44,693
  • 14
  • 105
  • 132