summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_out.cpp
diff options
context:
space:
mode:
authorKyle Suarez <kyle.suarez@mongodb.com>2018-08-30 10:45:29 -0400
committerKyle Suarez <kyle.suarez@mongodb.com>2018-08-30 10:45:29 -0400
commitb46de3f6c06fab5cf9b7ea0f4176b32ff544a4bf (patch)
treee12b893856d11b3f9833be20eb8c4f9de31dd35d /src/mongo/db/pipeline/document_source_out.cpp
parent8956deeef7bd4013d3de4092374fb9a2c329e2a5 (diff)
downloadmongo-b46de3f6c06fab5cf9b7ea0f4176b32ff544a4bf.tar.gz
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.
Diffstat (limited to 'src/mongo/db/pipeline/document_source_out.cpp')
-rw-r--r--src/mongo/db/pipeline/document_source_out.cpp10
1 files changed, 9 insertions, 1 deletions
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<DocumentSource> DocumentSourceOut::createFromBson(
BSONElement elem, const intrusive_ptr<ExpressionContext>& expCtx) {