summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/aggregation/unwind.js13
-rw-r--r--src/mongo/db/pipeline/document_source_unwind.cpp20
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();
}