diff options
-rw-r--r-- | jstests/aggregation/unwind.js | 13 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_unwind.cpp | 20 |
2 files changed, 25 insertions, 8 deletions
diff --git a/jstests/aggregation/unwind.js b/jstests/aggregation/unwind.js new file mode 100644 index 00000000000..5271317fa3e --- /dev/null +++ b/jstests/aggregation/unwind.js @@ -0,0 +1,13 @@ +t = db.agg_unwind; +t.drop(); + +t.insert( {_id : 1 } ); +t.insert( {_id : 2, x : null } ); +t.insert( {_id : 3, x : [] } ); +t.insert( {_id : 4, x : [1, 2] } ); +t.insert( {_id : 5, x : [3] } ); +t.insert( {_id : 6, x : 4 } ); + +var res = t.aggregate( [ { $unwind : "$x" }, { $sort : { _id : 1 } } ] ).toArray(); +assert.eq(4, res.length); +assert.eq([1,2,3,4],res.map(function(z){ return z.x; })); diff --git a/src/mongo/db/pipeline/document_source_unwind.cpp b/src/mongo/db/pipeline/document_source_unwind.cpp index 11c8d0880ec..4aa33633ca8 100644 --- a/src/mongo/db/pipeline/document_source_unwind.cpp +++ b/src/mongo/db/pipeline/document_source_unwind.cpp @@ -87,17 +87,11 @@ namespace mongo { return; } - // The target field must be an array to unwind. - uassert(15978, str::stream() << "Value at end of $unwind field path '" - << _unwindPath.getPath(true) << "' must be an Array, but is a " - << typeName(pathValue.getType()), - pathValue.getType() == Array); - _inputArray = pathValue; } boost::optional<Document> DocumentSourceUnwind::Unwinder::getNext() { - if (_inputArray.missing() || _index == _inputArray.getArrayLength()) + if (_inputArray.missing()) return boost::none; // If needed, this will automatically clone all the documents along the @@ -107,7 +101,17 @@ namespace mongo { // along the path leading to that will be replaced in order not to share // that change with any other clones (or the original). - _output.setNestedField(_unwindPathFieldIndexes, _inputArray[_index]); + if (_inputArray.getType() == Array) { + if (_index == _inputArray.getArrayLength()) + return boost::none; + _output.setNestedField(_unwindPathFieldIndexes, _inputArray[_index]); + } + else if (_index > 0) { + return boost::none; + } + else { + _output.setNestedField(_unwindPathFieldIndexes, _inputArray); + } _index++; return _output.peek(); } |