Search code examples
node.jsmongodbmongoose

How to make a correct aggregation request to an array to exclude an empty response


There is a database of this type: {_id: "...", shelf:{type:String}, books:{type:Array({ name :{type:String}})}} I need to extract all the shelves anyway, even if they don't have the book I'm looking for, my unsuccessful query looks like this:

let query = [ 
 {$match:{shelf: shelf}},
 {$unwind: "$books"}, 
 {$match: {$or:[ {'books.name ': {$exists: false}}, // If empty 
 {'books.name ': name}, // If there is a necessary book 
 {'books.name ': {$nin:name}} // If there is no necessary 
]}} ]

My desire to exclude an empty answer has led me to a dead end. there have been attempts to use $not, $ne, $nin. The result is one [ ] or undefined


Solution

  • I believe you are trying to get the shelves irrespective of existence of books. Your query has $unwind which is stopping this you need to pass an additional parameter (preserveNullAndEmptyArrays) like this

    let query = [{
        $match: {
          shelf: shelf
        }
      },
      {
        $unwind: {
          path: "$books",
          preserveNullAndEmptyArrays: true
        }
      },
      {
        $match: {
          $or: [{
              'books.name ': {
                $exists: false
              }
            }, // If empty 
            {
              'books.name ': name
            }, // If there is a necessary book 
            {
              'books.name ': {
                $nin: name
              }
            } // If there is no necessary 
          ]
        }
      }
    ]