From b46de3f6c06fab5cf9b7ea0f4176b32ff544a4bf Mon Sep 17 00:00:00 2001 From: Kyle Suarez Date: Thu, 30 Aug 2018 10:45:29 -0400 Subject: SERVER-36100 generate _id for $out uniqueKey if not present If the _id field is part of the $out "uniqueKey" but is not present in the document at the time of write, the $out stage will generate it automatically. We won't generate an _id if if isn't part of the "uniqueKey" so that DocumentSourceOutInPlaceReplace won't use it as part of the update. --- src/mongo/db/pipeline/document_source_out.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/mongo/db/pipeline/document_source_out.cpp') diff --git a/src/mongo/db/pipeline/document_source_out.cpp b/src/mongo/db/pipeline/document_source_out.cpp index 38b0e911734..4a3e4b4469a 100644 --- a/src/mongo/db/pipeline/document_source_out.cpp +++ b/src/mongo/db/pipeline/document_source_out.cpp @@ -127,6 +127,13 @@ DocumentSource::GetNextResult DocumentSourceOut::getNext() { for (; nextInput.isAdvanced(); nextInput = pSource->getNext()) { auto doc = nextInput.releaseDocument(); + // Generate an _id if the uniqueKey includes _id but the document doesn't have one. + if (_uniqueKeyIncludesId && doc.getField("_id"_sd).missing()) { + MutableDocument mutableDoc(std::move(doc)); + mutableDoc["_id"_sd] = Value(OID::gen()); + doc = mutableDoc.freeze(); + } + // Extract the unique key before converting the document to BSON. auto uniqueKey = document_path_support::extractPathsFromDoc(doc, _uniqueKeyFields); auto insertObj = doc.toBson(); @@ -220,7 +227,8 @@ DocumentSourceOut::DocumentSourceOut(NamespaceString outputNs, _done(false), _outputNs(std::move(outputNs)), _mode(mode), - _uniqueKeyFields(std::move(uniqueKey)) {} + _uniqueKeyFields(std::move(uniqueKey)), + _uniqueKeyIncludesId(_uniqueKeyFields.count("_id") == 1) {} intrusive_ptr DocumentSourceOut::createFromBson( BSONElement elem, const intrusive_ptr& expCtx) { -- cgit v1.2.1