summaryrefslogtreecommitdiff
path: root/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp')
-rw-r--r--src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp83
1 files changed, 63 insertions, 20 deletions
diff --git a/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp b/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp
index be234d0d95f..6481aa7bbf9 100644
--- a/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp
+++ b/src/mongo/db/timeseries/timeseries_commands_conversion_helper.cpp
@@ -50,6 +50,28 @@ namespace {
NamespaceString makeTimeseriesBucketsNamespace(const NamespaceString& nss) {
return nss.isTimeseriesBucketsCollection() ? nss : nss.makeTimeseriesBucketsNamespace();
}
+
+/**
+ * Converts the key field on time to 'control.min.$timeField' field. Depends on error checking from
+ * 'createBucketsSpecFromTimeseriesSpec()' which should be called before this function.
+ */
+BSONObj convertToTTLTimeField(const BSONObj& origKeyField, StringData timeField) {
+ BSONObjBuilder keyBuilder;
+ uassert(ErrorCodes::CannotCreateIndex,
+ str::stream() << "TTL indexes are single-field indexes, compound indexes do "
+ "not support TTL. Index spec: "
+ << origKeyField,
+ origKeyField.nFields() == 1);
+
+ const auto& firstElem = origKeyField.firstElement();
+ uassert(ErrorCodes::InvalidOptions,
+ "TTL indexes on non-time fields are not supported on time-series collections",
+ firstElem.fieldName() == timeField);
+
+ keyBuilder.appendAs(firstElem,
+ str::stream() << timeseries::kControlMinFieldNamePrefix << timeField);
+ return keyBuilder.obj();
+}
} // namespace
@@ -83,12 +105,17 @@ CreateIndexesCommand makeTimeseriesCreateIndexesCommand(OperationContext* opCtx,
std::vector<mongo::BSONObj> indexes;
for (const auto& origIndex : origIndexes) {
BSONObjBuilder builder;
- bool isBucketsIndexSpecCompatibleForDowngrade = true;
+ BSONObj keyField;
+ BSONObj originalKeyField;
+ bool isTTLIndex = false;
+ bool hasPartialFilterOnMetaField = false;
+ bool includeOriginalSpec = false;
+
for (const auto& elem : origIndex) {
if (elem.fieldNameStringData() == IndexDescriptor::kPartialFilterExprFieldName) {
- if (feature_flags::gTimeseriesMetricIndexes.isEnabledAndIgnoreFCV() &&
- serverGlobalParams.featureCompatibility.isFCVUpgradingToOrAlreadyLatest()) {
- isBucketsIndexSpecCompatibleForDowngrade = false;
+ if (feature_flags::gTimeseriesMetricIndexes.isEnabled(
+ serverGlobalParams.featureCompatibility)) {
+ includeOriginalSpec = true;
} else {
uasserted(ErrorCodes::InvalidOptions,
"Partial indexes are not supported on time-series collections");
@@ -135,7 +162,7 @@ CreateIndexesCommand makeTimeseriesCreateIndexesCommand(OperationContext* opCtx,
// planner, this will be true.
bool assumeNoMixedSchemaData = true;
- BSONObj bucketPred =
+ auto [hasMetricPred, bucketPred] =
BucketSpec::pushdownPredicate(expCtx,
options,
collationMatchesDefault,
@@ -144,6 +171,9 @@ CreateIndexesCommand makeTimeseriesCreateIndexesCommand(OperationContext* opCtx,
includeMetaField,
assumeNoMixedSchemaData,
BucketSpec::IneligiblePredicatePolicy::kError);
+
+ hasPartialFilterOnMetaField = !hasMetricPred;
+
builder.append(IndexDescriptor::kPartialFilterExprFieldName, bucketPred);
continue;
}
@@ -171,11 +201,11 @@ CreateIndexesCommand makeTimeseriesCreateIndexesCommand(OperationContext* opCtx,
}
if (elem.fieldNameStringData() == IndexDescriptor::kExpireAfterSecondsFieldName) {
- uasserted(ErrorCodes::InvalidOptions,
- "TTL indexes are not supported on time-series collections");
+ isTTLIndex = true;
+ builder.append(elem);
+ continue;
}
-
if (elem.fieldNameStringData() == IndexDescriptor::kUniqueFieldName) {
uassert(ErrorCodes::InvalidOptions,
"Unique indexes are not supported on time-series collections",
@@ -183,27 +213,28 @@ CreateIndexesCommand makeTimeseriesCreateIndexesCommand(OperationContext* opCtx,
}
if (elem.fieldNameStringData() == NewIndexSpec::kKeyFieldName) {
- auto pluginName = IndexNames::findPluginName(elem.Obj());
+ originalKeyField = elem.Obj();
+
+ auto pluginName = IndexNames::findPluginName(originalKeyField);
uassert(ErrorCodes::InvalidOptions,
"Text indexes are not supported on time-series collections",
pluginName != IndexNames::TEXT);
auto bucketsIndexSpecWithStatus =
- timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec(options, elem.Obj());
+ timeseries::createBucketsIndexSpecFromTimeseriesIndexSpec(options,
+ originalKeyField);
uassert(ErrorCodes::CannotCreateIndex,
str::stream() << bucketsIndexSpecWithStatus.getStatus().toString()
<< " Command request: " << redact(origCmd.toBSON({})),
bucketsIndexSpecWithStatus.isOK());
- if (!timeseries::isBucketsIndexSpecCompatibleForDowngrade(
+ if (timeseries::shouldIncludeOriginalSpec(
options,
BSON(NewIndexSpec::kKeyFieldName
<< bucketsIndexSpecWithStatus.getValue()))) {
- isBucketsIndexSpecCompatibleForDowngrade = false;
+ includeOriginalSpec = true;
}
-
- builder.append(NewIndexSpec::kKeyFieldName,
- std::move(bucketsIndexSpecWithStatus.getValue()));
+ keyField = std::move(bucketsIndexSpecWithStatus.getValue());
continue;
}
@@ -212,12 +243,24 @@ CreateIndexesCommand makeTimeseriesCreateIndexesCommand(OperationContext* opCtx,
builder.append(elem);
}
- if (feature_flags::gTimeseriesMetricIndexes.isEnabledAndIgnoreFCV() &&
- !isBucketsIndexSpecCompatibleForDowngrade) {
+ if (isTTLIndex) {
+ uassert(ErrorCodes::InvalidOptions,
+ "TTL indexes are not supported on time-series collections",
+ feature_flags::gTimeseriesScalabilityImprovements.isEnabled(
+ serverGlobalParams.featureCompatibility));
+ uassert(ErrorCodes::InvalidOptions,
+ "TTL indexes on time-series collections require a partialFilterExpression on "
+ "the metaField",
+ hasPartialFilterOnMetaField);
+ keyField = convertToTTLTimeField(originalKeyField, options.getTimeField());
+ }
+ builder.append(NewIndexSpec::kKeyFieldName, std::move(keyField));
+
+ if (feature_flags::gTimeseriesMetricIndexes.isEnabled(
+ serverGlobalParams.featureCompatibility) &&
+ includeOriginalSpec) {
// Store the original user index definition on the transformed index definition for the
- // time-series buckets collection if this is a newly supported index type on time-series
- // collections. This is to avoid any additional downgrade steps for index types already
- // supported in 5.0.
+ // time-series buckets collection.
builder.appendObject(IndexDescriptor::kOriginalSpecFieldName, origIndex.objdata());
}