diff options
Diffstat (limited to 'src/mongo/db/query/query_request_helper.cpp')
-rw-r--r-- | src/mongo/db/query/query_request_helper.cpp | 155 |
1 files changed, 2 insertions, 153 deletions
diff --git a/src/mongo/db/query/query_request_helper.cpp b/src/mongo/db/query/query_request_helper.cpp index 7db63a1427b..a8405f00e69 100644 --- a/src/mongo/db/query/query_request_helper.cpp +++ b/src/mongo/db/query/query_request_helper.cpp @@ -38,6 +38,8 @@ #include "mongo/bson/simple_bsonobj_comparator.h" #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/dbmessage.h" +#include "mongo/db/matcher/expression_geo.h" +#include "mongo/db/query/canonical_query.h" namespace mongo { @@ -414,158 +416,5 @@ StatusWith<std::unique_ptr<FindCommandRequest>> fromLegacyQuery(NamespaceStringO return std::move(findCommand); } -StatusWith<BSONObj> asAggregationCommand(const FindCommandRequest& findCommand) { - BSONObjBuilder aggregationBuilder; - - // The find command will translate away ntoreturn above this layer. - tassert(5746106, "ntoreturn should not be set in the findCommand", !findCommand.getNtoreturn()); - - // First, check if this query has options that are not supported in aggregation. - if (!findCommand.getMin().isEmpty()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kMinFieldName - << " not supported in aggregation."}; - } - if (!findCommand.getMax().isEmpty()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kMaxFieldName - << " not supported in aggregation."}; - } - if (findCommand.getReturnKey()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kReturnKeyFieldName - << " not supported in aggregation."}; - } - if (findCommand.getShowRecordId()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kShowRecordIdFieldName - << " not supported in aggregation."}; - } - if (findCommand.getTailable()) { - return {ErrorCodes::InvalidPipelineOperator, - "Tailable cursors are not supported in aggregation."}; - } - if (findCommand.getNoCursorTimeout()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kNoCursorTimeoutFieldName - << " not supported in aggregation."}; - } - if (findCommand.getAllowPartialResults()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kAllowPartialResultsFieldName - << " not supported in aggregation."}; - } - if (findCommand.getSort()[query_request_helper::kNaturalSortField]) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Sort option " << query_request_helper::kNaturalSortField - << " not supported in aggregation."}; - } - // The aggregation command normally does not support the 'singleBatch' option, but we make a - // special exception if 'limit' is set to 1. - if (findCommand.getSingleBatch() && findCommand.getLimit().value_or(0) != 1LL) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kSingleBatchFieldName - << " not supported in aggregation."}; - } - if (findCommand.getReadOnce()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kReadOnceFieldName - << " not supported in aggregation."}; - } - - if (findCommand.getAllowSpeculativeMajorityRead()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " - << FindCommandRequest::kAllowSpeculativeMajorityReadFieldName - << " not supported in aggregation."}; - } - - if (findCommand.getRequestResumeToken()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kRequestResumeTokenFieldName - << " not supported in aggregation."}; - } - - if (!findCommand.getResumeAfter().isEmpty()) { - return {ErrorCodes::InvalidPipelineOperator, - str::stream() << "Option " << FindCommandRequest::kResumeAfterFieldName - << " not supported in aggregation."}; - } - - // Now that we've successfully validated this QR, begin building the aggregation command. - aggregationBuilder.append("aggregate", - findCommand.getNamespaceOrUUID().nss() - ? findCommand.getNamespaceOrUUID().nss()->coll() - : ""); - - // Construct an aggregation pipeline that finds the equivalent documents to this query request. - BSONArrayBuilder pipelineBuilder(aggregationBuilder.subarrayStart("pipeline")); - if (!findCommand.getFilter().isEmpty()) { - BSONObjBuilder matchBuilder(pipelineBuilder.subobjStart()); - matchBuilder.append("$match", findCommand.getFilter()); - matchBuilder.doneFast(); - } - if (!findCommand.getSort().isEmpty()) { - BSONObjBuilder sortBuilder(pipelineBuilder.subobjStart()); - sortBuilder.append("$sort", findCommand.getSort()); - sortBuilder.doneFast(); - } - if (findCommand.getSkip()) { - BSONObjBuilder skipBuilder(pipelineBuilder.subobjStart()); - skipBuilder.append("$skip", *findCommand.getSkip()); - skipBuilder.doneFast(); - } - if (findCommand.getLimit()) { - BSONObjBuilder limitBuilder(pipelineBuilder.subobjStart()); - limitBuilder.append("$limit", *findCommand.getLimit()); - limitBuilder.doneFast(); - } - if (!findCommand.getProjection().isEmpty()) { - BSONObjBuilder projectBuilder(pipelineBuilder.subobjStart()); - projectBuilder.append("$project", findCommand.getProjection()); - projectBuilder.doneFast(); - } - pipelineBuilder.doneFast(); - - // The aggregation 'cursor' option is always set, regardless of the presence of batchSize. - BSONObjBuilder batchSizeBuilder(aggregationBuilder.subobjStart("cursor")); - if (findCommand.getBatchSize()) { - batchSizeBuilder.append(FindCommandRequest::kBatchSizeFieldName, - *findCommand.getBatchSize()); - } - batchSizeBuilder.doneFast(); - - // Other options. - aggregationBuilder.append("collation", findCommand.getCollation()); - int maxTimeMS = findCommand.getMaxTimeMS() ? static_cast<int>(*findCommand.getMaxTimeMS()) : 0; - if (maxTimeMS > 0) { - aggregationBuilder.append(cmdOptionMaxTimeMS, maxTimeMS); - } - if (!findCommand.getHint().isEmpty()) { - aggregationBuilder.append(FindCommandRequest::kHintFieldName, findCommand.getHint()); - } - if (findCommand.getReadConcern()) { - aggregationBuilder.append("readConcern", *findCommand.getReadConcern()); - } - if (!findCommand.getUnwrappedReadPref().isEmpty()) { - aggregationBuilder.append(FindCommandRequest::kUnwrappedReadPrefFieldName, - findCommand.getUnwrappedReadPref()); - } - if (findCommand.getAllowDiskUse()) { - aggregationBuilder.append(FindCommandRequest::kAllowDiskUseFieldName, - static_cast<bool>(findCommand.getAllowDiskUse())); - } - if (findCommand.getLegacyRuntimeConstants()) { - BSONObjBuilder rtcBuilder( - aggregationBuilder.subobjStart(FindCommandRequest::kLegacyRuntimeConstantsFieldName)); - findCommand.getLegacyRuntimeConstants()->serialize(&rtcBuilder); - rtcBuilder.doneFast(); - } - if (findCommand.getLet()) { - aggregationBuilder.append(FindCommandRequest::kLetFieldName, *findCommand.getLet()); - } - return StatusWith<BSONObj>(aggregationBuilder.obj()); -} - } // namespace query_request_helper } // namespace mongo |