diff options
author | Benety Goh <benety@mongodb.com> | 2020-12-18 16:18:04 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-12-18 22:17:28 +0000 |
commit | a56d682b08d9a72ef54fde6d47c978b8eb54bfbc (patch) | |
tree | 603c9d290766759b3f9503ec90cfd0bb655f5500 | |
parent | a2a154c9a9aa133603d0f2797d77479a7f192ac8 (diff) | |
download | mongo-a56d682b08d9a72ef54fde6d47c978b8eb54bfbc.tar.gz |
SERVER-53395 time-series insert uses delta updates instead of classic update
-rw-r--r-- | src/mongo/db/commands/write_commands/write_commands.cpp | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/src/mongo/db/commands/write_commands/write_commands.cpp b/src/mongo/db/commands/write_commands/write_commands.cpp index 954154ba5fb..443f01bb160 100644 --- a/src/mongo/db/commands/write_commands/write_commands.cpp +++ b/src/mongo/db/commands/write_commands/write_commands.cpp @@ -65,6 +65,7 @@ #include "mongo/db/write_concern.h" #include "mongo/s/stale_exception.h" #include "mongo/util/fail_point.h" +#include "mongo/util/string_map.h" namespace mongo { namespace { @@ -175,16 +176,56 @@ write_ops::UpdateOpEntry makeTimeseriesUpdateOpEntry(const OID& bucketId, const BSONObj& metadata) { BSONObjBuilder updateBuilder; { - BSONObjBuilder setOpBuilder(updateBuilder.subobjStart("$set")); - setOpBuilder.append("control.min", data.bucketMin); - setOpBuilder.append("control.max", data.bucketMax); - auto metadataElem = metadata.firstElement(); - appendTimeseriesDataFields( - data.docs, metadataElem, data.numCommittedMeasurements, &setOpBuilder); + // doc_diff::kSubDiffSectionFieldPrefix + <field name> + BSONObjBuilder controlBuilder(updateBuilder.subobjStart("scontrol")); + { + // doc_diff::kUpdateSectionFieldName + BSONObjBuilder controlUpdateBuilder(controlBuilder.subobjStart("u")); + controlUpdateBuilder.append("min", data.bucketMin); + controlUpdateBuilder.append("max", data.bucketMax); + } } + { + // doc_diff::kSubDiffSectionFieldPrefix + <field name> => {<index_0>: ..., <index_1>: ...} + StringDataMap<BSONObjBuilder> dataFieldBuilders; + auto metadataElem = metadata.firstElement(); + auto count = data.numCommittedMeasurements; + for (const auto& doc : data.docs) { + for (const auto& elem : doc) { + auto key = elem.fieldNameStringData(); + if (metadataElem && key == metadataElem.fieldNameStringData()) { + continue; + } + auto& builder = dataFieldBuilders[key]; + builder.appendAs(elem, std::to_string(count)); + } + count++; + } - write_ops::UpdateModification u(updateBuilder.obj(), - write_ops::UpdateModification::ClassicTag{}); + // doc_diff::kSubDiffSectionFieldPrefix + <field name> + BSONObjBuilder dataBuilder(updateBuilder.subobjStart("sdata")); + BSONObjBuilder newDataFieldsBuilder; + for (auto& pair : dataFieldBuilders) { + // Existing 'data' fields with measurements require different treatment from fields + // not observed before (missing from control.min and control.max). + if (data.newFieldNamesToBeInserted.count(pair.first)) { + newDataFieldsBuilder.append(pair.first, pair.second.obj()); + } + } + auto newDataFields = newDataFieldsBuilder.obj(); + if (!newDataFields.isEmpty()) { + dataBuilder.append(doc_diff::kInsertSectionFieldName, newDataFields); + } + for (auto& pair : dataFieldBuilders) { + // Existing 'data' fields with measurements require different treatment from fields + // not observed before (missing from control.min and control.max). + if (!data.newFieldNamesToBeInserted.count(pair.first)) { + dataBuilder.append(doc_diff::kSubDiffSectionFieldPrefix + pair.first.toString(), + BSON(doc_diff::kInsertSectionFieldName << pair.second.obj())); + } + } + } + write_ops::UpdateModification u(updateBuilder.obj(), write_ops::UpdateModification::DiffTag{}); write_ops::UpdateOpEntry update(BSON("_id" << bucketId), std::move(u)); invariant(!update.getMulti(), bucketId.toString()); invariant(!update.getUpsert(), bucketId.toString()); |