Search code examples
node.jsmongodbaggregation-frameworknode-mongodb-native

Node Mongodb Driver: different result on aggregate


how you doing? I have a trouble making a aggregation in my project, my aggregation result is different in Robo3T and Node.

db.getCollection('companies').aggregate([
    { '$match': { _id: { '$eq': ObjectId("5e30a4fe11e6e80d7fb544a4")} } },
    { $unwind: '$jobVacancies' },
    {
      $project: {
          jobVacancies: {
              _id: 1,
              name: 1,
              city: 1,
              openingDate: 1,
              closingDate: 1,
              createdAt: 1,
              quantity: 1,
              steps: {
                  $filter: {
                      input: '$jobVacancies.steps',
                      as: 'step',
                      cond: {
                          $and: [
                              { $eq: ['$$step.order', 0] },
                              { $ne: ['$$step.users', undefined] },
                              { $ne: ['$$step.users', null] },
                              { $ne: ['$$step.users', []] },
                          ],
                      },
                  },
              },
          },
      },
  },
  { $match: { 'jobVacancies.steps': { $ne: [] } } },
])

In Robo3T this is returning 1 object, but in Node (the same aggregation) is resulting 6 objects. Can you help me? Thank you

EDIT Nodejs:

The first match create the ObjectId match for company in context of GraphQL based on my filter.

const companies = await this.MongoClient.db
            .collection('companies')
            .aggregate([
                {
                    $match: await this.getFilterObject(
                        filters.filter(f => !f.field.includes('$$jobVacancy') && !f.field.includes('StepOrder')),
                    ),
                },
                { $unwind: '$jobVacancies' },
                {
                    $project: {
                        jobVacancies: {
                            _id: 1,
                            name: 1,
                            city: 1,
                            openingDate: 1,
                            closingDate: 1,
                            createdAt: 1,
                            quantity: 1,
                            steps: {
                                $filter: {
                                    input: '$jobVacancies.steps',
                                    as: 'step',
                                    cond: {
                                        $and: [
                                            { $eq: ['$$step.order', order] },
                                            { $ne: ['$$step.users', undefined] },
                                            { $ne: ['$$step.users', null] },
                                            { $ne: ['$$step.users', []] },
                                        ],
                                    },
                                },
                            },
                        },
                    },
                },
                { $match: { 'jobVacancies.steps': { $ne: [] } } },
            ])
            .toArray();

EDIT 3 This is the result of console.dir (with {depth:null}) of the pipeline

[
   {
     '$match': {
       _id: {
         '$eq': ObjectID {
           _bsontype: 'ObjectID',
           id: Buffer [Uint8Array] [
              94,  48, 164, 254,  17,
             230, 232,  13, 127, 181,
              68, 164
           ]
         }
       }
     }
   },
   { '$unwind': '$jobVacancies' },
   {
     '$project': {
       jobVacancies: {
         _id: 1,
         name: 1,
         city: 1,
         openingDate: 1,
         closingDate: 1,
         createdAt: 1,
         quantity: 1,
         steps: {
           '$filter': {
             input: '$jobVacancies.steps',
             as: 'step',
             cond: {
               '$and': [
                 { '$eq': [ '$$step.order', 0 ] },
                 { '$ne': [ '$$step.users', undefined ] },
                 { '$ne': [ '$$step.users', null ] },
                 { '$ne': [ '$$step.users', [] ] }
               ]
             }
           }
         }
       }
     }
   },
   { '$match': { 'jobVacancies.steps': { '$ne': [] } } }
 ]

Solution

  • I think i found the solution, the document is created with properties:

    jobVacancies: { 
        steps: { 
            users: [] 
        } 
    }
    

    But sometimes users array is undefined in mongodb, so I verify with { '$ne': [ '$$step.users', undefined ] } I think JS undefined is different then mongodb undefined, so I initialized all steps with an empty array of users, and removed this verification and worked! –