3

Lets say I am using a $unwind on a field in mongoose schema
According to the above link If field is not present then unwind will ignore input document
How can I prevent that so that result of query is returned without unwinding process even if field is not present i.e input document is not ignored

if a particular field exists   
  I want to do unwind and some more stuff (project and group) 
else
  I want input document no changes in this case  
Sidharth Guglani
  • 105
  • 1
  • 11

1 Answers1

4

According to the above link If field is not present then unwind will throw an error

No, it don't:

  • If a value in the field specified by the field path is not an array, db.collection.aggregate() generates an error.
  • If you specify a path for a field that does not exist in an input document, the pipeline ignores the input document and will not output documents for that input document.

Here is a simple example:

> db.test.insert({a:[1]})
> db.test.insert({})

> db.test.aggregate({$unwind:'$a'})
{ "_id" : ObjectId("557362a17b97d77c38793c21"), "a" : 1 }
// no error -- but unwind only the document having the `a` field.

But:

> db.test.insert({a:2})
> db.test.aggregate({$unwind:'$a'})
// will result in error 15978:
// """Value at end of $unwind field path '$a' must be an Array,
//    but is a NumberDouble"""

As per your edit, if you need to keep documents with a missing field to unwind, you can $project a default value using $ifNull:

> db.test.find()
{ "_id" : ObjectId("557362a17b97d77c38793c21"), "a" : [ 1 ] }
{ "_id" : ObjectId("557362a57b97d77c38793c22") }

> db.test.aggregate([
    {$project: { a: { $ifNull: ['$a', [ null ]]}}},
    {$unwind: "$a"}
])
{ "_id" : ObjectId("557362a17b97d77c38793c21"), "a" : 1 }
{ "_id" : ObjectId("557362a57b97d77c38793c22"), "a" : null }
Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125