diff options
author | Dianna Hohensee <dianna.hohensee@mongodb.com> | 2021-03-23 23:31:52 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-03-25 22:48:02 +0000 |
commit | e0f87dc63d1d430c83515dacf9b7a57aa503ac44 (patch) | |
tree | 2ea4cb969c745155fe75d44f91c0b39a76dabac0 /src | |
parent | 6afd283045dc43c0b249424ba03a72b89e5ad8c6 (diff) | |
download | mongo-e0f87dc63d1d430c83515dacf9b7a57aa503ac44.tar.gz |
SERVER-54639 make list_indexes.cpp time-series conversion helper functions generic
Diffstat (limited to 'src')
8 files changed, 68 insertions, 62 deletions
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index bb75219b9b8..36e1596459e 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -638,8 +638,8 @@ std::unique_ptr<CreateIndexesCommand> makeTimeseriesCreateIndexesCommand( for (const auto& elem : origIndex) { if (elem.fieldNameStringData() == NewIndexSpec::kKeyFieldName) { auto bucketsIndexSpecWithStatus = - timeseries::convertTimeseriesIndexSpecToBucketsIndexSpec(*timeseriesOptions, - elem.Obj()); + timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec(*timeseriesOptions, + elem.Obj()); uassert(ErrorCodes::CannotCreateIndex, str::stream() << bucketsIndexSpecWithStatus.getStatus().toString() << " Command request: " << redact(origCmd.toBSON({})), diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp index 85c1d0b5e01..ca3768c8698 100644 --- a/src/mongo/db/commands/dbcommands.cpp +++ b/src/mongo/db/commands/dbcommands.cpp @@ -122,7 +122,7 @@ std::unique_ptr<CollMod> makeTimeseriesCollModCommand(OperationContext* opCtx, auto index = origCmd.getIndex(); if (index && index->getKeyPattern()) { - auto bucketsIndexSpecWithStatus = timeseries::convertTimeseriesIndexSpecToBucketsIndexSpec( + auto bucketsIndexSpecWithStatus = timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec( *timeseriesOptions, *index->getKeyPattern()); uassert(ErrorCodes::IndexNotFound, diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp index 85d1c56b929..a2a5be13db7 100644 --- a/src/mongo/db/commands/drop_indexes.cpp +++ b/src/mongo/db/commands/drop_indexes.cpp @@ -90,7 +90,7 @@ std::unique_ptr<DropIndexes> makeTimeseriesDropIndexesCommand(OperationContext* const auto& origIndex = origCmd.getIndex(); if (auto keyPtr = stdx::get_if<BSONObj>(&origIndex)) { auto bucketsIndexSpecWithStatus = - timeseries::convertTimeseriesIndexSpecToBucketsIndexSpec(*timeseriesOptions, *keyPtr); + timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec(*timeseriesOptions, *keyPtr); uassert(ErrorCodes::IndexNotFound, str::stream() << bucketsIndexSpecWithStatus.getStatus().toString() diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp index 5d207392b6a..ee927bb7dd6 100644 --- a/src/mongo/db/commands/list_indexes.cpp +++ b/src/mongo/db/commands/list_indexes.cpp @@ -63,51 +63,6 @@ namespace mongo { namespace { /** - * Converts buckets collection index specs to the time-series collection schema. - * Returns a list of index specs mapped from the bucket collection schema. - */ -std::list<BSONObj> makeTimeseriesIndexSpecs(const TimeseriesOptions& timeseriesOptions, - const std::list<BSONObj>& bucketsIndexSpecs) { - std::list<BSONObj> indexSpecs; - for (const auto& bucketsIndexSpec : bucketsIndexSpecs) { - // TODO(SERVER-54639): Map index specs from bucket collection using helper function. - BSONObjBuilder builder; - bool skip = false; - for (const auto& elem : bucketsIndexSpec) { - if (elem.fieldNameStringData() == ListIndexesReplyItem::kKeyFieldName) { - auto key = timeseries::convertBucketsIndexSpecToTimeseriesIndexSpec( - timeseriesOptions, elem.Obj()); - if (key.isEmpty()) { - // Skip index spec due to failed conversion. - skip = true; - break; - } - builder.append(ListIndexesReplyItem::kKeyFieldName, key); - continue; - } - // Besides 'key', fields such as 'v' and 'name' commonly appear in the spec. - // Depending on the index options, other fields that may be appended here - // include 'sparse', 'hidden', 'collation'. - // { - // v: 2, - // name: 'mm_1', - // ... - // sparse: true, - // ... - // } - // For a complete list, refer to: - // https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#options-for-all-index-types - builder.append(elem); - } - if (skip) { - continue; - } - indexSpecs.push_back(builder.obj()); - } - return indexSpecs; -} - -/** * Returns index specs, with resolved namespace, from the catalog for this listIndexes request. */ using IndexSpecsWithNamespaceString = std::pair<std::list<BSONObj>, NamespaceString>; @@ -128,7 +83,7 @@ IndexSpecsWithNamespaceString getIndexSpecsWithNamespaceString(OperationContext* coll); return std::make_pair( - makeTimeseriesIndexSpecs( + timeseries::createTimeseriesIndexesFromBucketsIndexes( *timeseriesOptions, listIndexesInLock(opCtx, coll, bucketsNss, cmd.getIncludeBuildUUIDs())), *origNss); diff --git a/src/mongo/db/timeseries/timeseries_field_names.h b/src/mongo/db/timeseries/timeseries_field_names.h index fdbd89240b4..7bc3a3c0417 100644 --- a/src/mongo/db/timeseries/timeseries_field_names.h +++ b/src/mongo/db/timeseries/timeseries_field_names.h @@ -41,5 +41,8 @@ static constexpr StringData kControlMinFieldNamePrefix = "control.min."_sd; static constexpr StringData kTimeFieldName = "timeField"_sd; static constexpr StringData kMetaFieldName = "metaField"_sd; +// These are hard-coded field names in index specs. +static constexpr StringData kKeyFieldName = "key"_sd; + } // namespace timeseries } // namespace mongo diff --git a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.cpp b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.cpp index 49b9a15d3a7..2a14169b28f 100644 --- a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.cpp +++ b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.cpp @@ -57,7 +57,7 @@ boost::optional<TimeseriesOptions> getTimeseriesOptions(OperationContext* opCtx, return view->timeseries(); } -StatusWith<BSONObj> convertTimeseriesIndexSpecToBucketsIndexSpec( +StatusWith<BSONObj> createBucketsIndexSpecFromTimeseriesIndexSpec( const TimeseriesOptions& timeseriesOptions, const BSONObj& timeseriesIndexSpecBSON) { auto timeField = timeseriesOptions.getTimeField(); auto metaField = timeseriesOptions.getMetaField(); @@ -127,8 +127,8 @@ StatusWith<BSONObj> convertTimeseriesIndexSpecToBucketsIndexSpec( return builder.obj(); } -BSONObj convertBucketsIndexSpecToTimeseriesIndexSpec(const TimeseriesOptions& timeseriesOptions, - const BSONObj& bucketsIndexSpecBSON) { +boost::optional<BSONObj> createTimeseriesIndexSpecFromBucketsIndexSpec( + const TimeseriesOptions& timeseriesOptions, const BSONObj& bucketsIndexSpecBSON) { auto timeField = timeseriesOptions.getTimeField(); auto metaField = timeseriesOptions.getMetaField(); @@ -183,5 +183,33 @@ BSONObj convertBucketsIndexSpecToTimeseriesIndexSpec(const TimeseriesOptions& ti return builder.obj(); } +boost::optional<BSONObj> createTimeseriesIndexFromBucketsIndex( + const TimeseriesOptions& timeseriesOptions, const BSONObj& bucketsIndex) { + if (bucketsIndex.hasField(kKeyFieldName)) { + auto timeseriesKeyValue = createTimeseriesIndexSpecFromBucketsIndexSpec( + timeseriesOptions, bucketsIndex.getField(kKeyFieldName).Obj()); + if (timeseriesKeyValue) { + // This creates a bsonobj copy with a modified kKeyFieldName field set to + // timeseriesKeyValue. + return bucketsIndex.addFields(BSON(kKeyFieldName << timeseriesKeyValue.get()), + StringDataSet{kKeyFieldName}); + } + } + return boost::none; +} + +std::list<BSONObj> createTimeseriesIndexesFromBucketsIndexes( + const TimeseriesOptions& timeseriesOptions, const std::list<BSONObj>& bucketsIndexes) { + std::list<BSONObj> indexSpecs; + for (const auto& bucketsIndex : bucketsIndexes) { + auto timeseriesIndex = + createTimeseriesIndexFromBucketsIndex(timeseriesOptions, bucketsIndex); + if (timeseriesIndex) { + indexSpecs.push_back(timeseriesIndex->getOwned()); + } + } + return indexSpecs; +} + } // namespace timeseries } // namespace mongo diff --git a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.h b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.h index aec7cda44c7..a387a1022d7 100644 --- a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.h +++ b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions.h @@ -55,15 +55,15 @@ boost::optional<TimeseriesOptions> getTimeseriesOptions(OperationContext* opCtx, * * Returns an error if the specified 'timeseriesKeyBSON' is invalid for the time-series collection. */ -StatusWith<BSONObj> convertTimeseriesIndexSpecToBucketsIndexSpec( +StatusWith<BSONObj> createBucketsIndexSpecFromTimeseriesIndexSpec( const TimeseriesOptions& timeseriesOptions, const BSONObj& timeseriesIndexSpecBSON); /** * Maps the buckets collection index spec 'bucketsIndexSpecBSON' to the index schema of the * time-series collection using the information provided in 'timeseriesOptions'. * - * If 'bucketsIndexSpecBSON' does not match a valid time-series index format, then an empty BSONObj - * is returned. + * If 'bucketsIndexSpecBSON' does not match a valid time-series index format, then boost::none is + * returned. * * Conversion Example: * On a time-series collection with 'tm' time field and 'mm' metadata field, @@ -79,8 +79,27 @@ StatusWith<BSONObj> convertTimeseriesIndexSpecToBucketsIndexSpec( * 'tm': 1 * } */ -BSONObj convertBucketsIndexSpecToTimeseriesIndexSpec(const TimeseriesOptions& timeseriesOptions, - const BSONObj& bucketsIndexSpecBSON); +boost::optional<BSONObj> createTimeseriesIndexSpecFromBucketsIndexSpec( + const TimeseriesOptions& timeseriesOptions, const BSONObj& bucketsIndexSpecBSON); + +/** + * Returns a time-series collection index spec equivalent to the given 'bucketsIndex' using the + * time-series specifications provided in 'timeseriesOptions'. Returns boost::none if the + * buckets index is not supported on a time-series collection. + * + * Copies and modifies the 'key' field of the buckets index, but otherwises copies all of the fields + * over unaltered. + */ +boost::optional<BSONObj> createTimeseriesIndexFromBucketsIndex( + const TimeseriesOptions& timeseriesOptions, const BSONObj& bucketsIndex); + +/** + * Returns a list of time-series collection index specs equivalent to the given 'bucketsIndexSpecs' + * using the time-series specifications provided in 'timeseriesOptions'. If any of the buckets + * indexes is not supported on a time-series collection, it will be ommitted from the results. + */ +std::list<BSONObj> createTimeseriesIndexesFromBucketsIndexes( + const TimeseriesOptions& timeseriesOptions, const std::list<BSONObj>& bucketsIndexes); } // namespace timeseries } // namespace mongo diff --git a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions_test.cpp b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions_test.cpp index 8da8db97f2a..6c5320c9fd3 100644 --- a/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions_test.cpp +++ b/src/mongo/db/timeseries/timeseries_index_schema_conversion_functions_test.cpp @@ -70,7 +70,7 @@ void testBothWaysIndexSpecConversion(const TimeseriesOptions& timeseriesOptions, bool testShouldSucceed = true) { // Test time-series => buckets schema conversion. - auto swBucketsIndexSpecs = timeseries::convertTimeseriesIndexSpecToBucketsIndexSpec( + auto swBucketsIndexSpecs = timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec( timeseriesOptions, timeseriesIndexSpec); if (testShouldSucceed) { @@ -82,15 +82,16 @@ void testBothWaysIndexSpecConversion(const TimeseriesOptions& timeseriesOptions, // Test buckets => time-series schema conversion. - auto timeseriesIndexSpecResult = timeseries::convertBucketsIndexSpecToTimeseriesIndexSpec( + auto timeseriesIndexSpecResult = timeseries::createTimeseriesIndexSpecFromBucketsIndexSpec( timeseriesOptions, bucketsIndexSpec); if (testShouldSucceed) { - ASSERT_BSONOBJ_EQ(timeseriesIndexSpec, timeseriesIndexSpecResult); + ASSERT(timeseriesIndexSpecResult); + ASSERT_BSONOBJ_EQ(timeseriesIndexSpec, timeseriesIndexSpecResult.get()); } else { // A buckets collection index spec that does not conform to the supported time-series index // spec schema should be converted to an empty time-series index spec result. - ASSERT(timeseriesIndexSpecResult.isEmpty()); + ASSERT(!timeseriesIndexSpecResult); } } |