diff options
author | Jacob Evans <jacob.evans@10gen.com> | 2019-08-09 13:04:37 -0400 |
---|---|---|
committer | Jacob Evans <jacob.evans@10gen.com> | 2019-08-23 13:38:19 -0400 |
commit | 05653b6b9d25a4168ae310488949adaa8e163bfc (patch) | |
tree | fa65221bade4d9cf4b2249f30179d879efab95c0 /src/mongo | |
parent | 441871aa17a4c77175c8c6d6c8ac94eadecbfd33 (diff) | |
download | mongo-05653b6b9d25a4168ae310488949adaa8e163bfc.tar.gz |
SERVER-42902 Update the MR response formatting code to run on a pipeline
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/commands/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/commands/map_reduce_agg.cpp | 28 | ||||
-rw-r--r-- | src/mongo/db/commands/map_reduce_agg.h | 5 | ||||
-rw-r--r-- | src/mongo/db/query/SConscript | 8 | ||||
-rw-r--r-- | src/mongo/db/query/map_reduce_output_format.cpp | 90 | ||||
-rw-r--r-- | src/mongo/db/query/map_reduce_output_format.h | 63 | ||||
-rw-r--r-- | src/mongo/db/query/map_reduce_output_format_test.cpp (renamed from src/mongo/db/query/mr_response_formatter_test.cpp) | 90 | ||||
-rw-r--r-- | src/mongo/db/query/mr_response_formatter.cpp | 105 | ||||
-rw-r--r-- | src/mongo/db/query/mr_response_formatter.h | 90 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_map_reduce_agg.cpp | 9 |
10 files changed, 222 insertions, 268 deletions
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index a8402d10327..8351ec93f75 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -394,9 +394,9 @@ env.Library( '$BUILD_DIR/mongo/db/dbhelpers', '$BUILD_DIR/mongo/db/exec/stagedebug_cmd', '$BUILD_DIR/mongo/db/index_builds_coordinator_interface', - '$BUILD_DIR/mongo/db/query/mr_response_formatter', '$BUILD_DIR/mongo/db/pipeline/mongo_process_interface', '$BUILD_DIR/mongo/db/pipeline/pipeline', + '$BUILD_DIR/mongo/db/query/map_reduce_output_format', '$BUILD_DIR/mongo/db/repl/dbcheck', '$BUILD_DIR/mongo/db/repl/oplog', '$BUILD_DIR/mongo/db/repl/repl_coordinator_interface', diff --git a/src/mongo/db/commands/map_reduce_agg.cpp b/src/mongo/db/commands/map_reduce_agg.cpp index 840618ce9d1..c94116a3934 100644 --- a/src/mongo/db/commands/map_reduce_agg.cpp +++ b/src/mongo/db/commands/map_reduce_agg.cpp @@ -35,11 +35,12 @@ #include "mongo/db/commands/map_reduce_agg.h" #include "mongo/db/commands/map_reduce_gen.h" #include "mongo/db/db_raii.h" +#include "mongo/db/namespace_string.h" #include "mongo/db/pipeline/document_source.h" #include "mongo/db/pipeline/expression_context.h" #include "mongo/db/pipeline/pipeline.h" #include "mongo/db/pipeline/pipeline_d.h" -#include "mongo/db/query/mr_response_formatter.h" +#include "mongo/db/query/map_reduce_output_format.h" #include "mongo/util/intrusive_counter.h" namespace mongo { @@ -95,8 +96,31 @@ bool runAggregationMapReduce(OperationContext* opCtx, const BSONObj& cmd, std::string& errmsg, BSONObjBuilder& result) { + auto exhaustPipelineIntoBSONArray = [](auto&& pipeline) { + BSONArrayBuilder bab; + while (auto&& doc = pipeline->getNext()) + bab.append(doc->toBson()); + return bab.arr(); + }; + auto parsedMr = MapReduce::parse(IDLParserErrorContext("MapReduce"), cmd); - [[maybe_unused]] auto pipe = translateFromMR(parsedMr, makeExpressionContext(opCtx, parsedMr)); + bool inMemory = parsedMr.getOutOptions().getOutputType() == OutputType::InMemory; + + auto pipe = translateFromMR(parsedMr, makeExpressionContext(opCtx, parsedMr)); + + if (inMemory) + map_reduce_output_format::appendInlineResponse(exhaustPipelineIntoBSONArray(pipe), + parsedMr.getVerbose().get_value_or(false), + false, + &result); + else + map_reduce_output_format::appendOutResponse( + NamespaceString(parsedMr.getOutOptions().getDatabaseName(), + parsedMr.getOutOptions().getCollectionName()), + boost::get_optional_value_or(parsedMr.getVerbose(), false), + false, + &result); + return true; } diff --git a/src/mongo/db/commands/map_reduce_agg.h b/src/mongo/db/commands/map_reduce_agg.h index c946f74c380..8ac5d0ead5f 100644 --- a/src/mongo/db/commands/map_reduce_agg.h +++ b/src/mongo/db/commands/map_reduce_agg.h @@ -27,10 +27,6 @@ * it in the license file. */ -#include "mongo/bson/bsonobj.h" -#include "mongo/bson/bsonobjbuilder.h" -#include "mongo/db/operation_context.h" - namespace mongo { bool runAggregationMapReduce(OperationContext* opCtx, @@ -38,4 +34,5 @@ bool runAggregationMapReduce(OperationContext* opCtx, const BSONObj& cmd, std::string& errmsg, BSONObjBuilder& result); + } // namespace mongo diff --git a/src/mongo/db/query/SConscript b/src/mongo/db/query/SConscript index 0260575ec37..ef3c6075095 100644 --- a/src/mongo/db/query/SConscript +++ b/src/mongo/db/query/SConscript @@ -104,9 +104,9 @@ env.Library( ) env.Library( - target='mr_response_formatter', + target='map_reduce_output_format', source=[ - 'mr_response_formatter.cpp' + 'map_reduce_output_format.cpp', ], LIBDEPS=[ '$BUILD_DIR/mongo/base', @@ -250,7 +250,7 @@ env.CppUnitTest( "killcursors_request_test.cpp", "killcursors_response_test.cpp", "lru_key_value_test.cpp", - "mr_response_formatter_test.cpp", + 'map_reduce_output_format_test.cpp', "parsed_distinct_test.cpp", "parsed_projection_test.cpp", "plan_cache_indexability_test.cpp", @@ -284,7 +284,7 @@ env.CppUnitTest( "command_request_response", "explain_options", "hint_parser", - "mr_response_formatter", + "map_reduce_output_format", "query_common", "query_planner", "query_planner_test_fixture", diff --git a/src/mongo/db/query/map_reduce_output_format.cpp b/src/mongo/db/query/map_reduce_output_format.cpp new file mode 100644 index 00000000000..c3c9859a423 --- /dev/null +++ b/src/mongo/db/query/map_reduce_output_format.cpp @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/db/query/map_reduce_output_format.h" + +namespace mongo::map_reduce_output_format { + +namespace { + +void appendMetadataFields(bool verbose, bool inMongos, BSONObjBuilder* resultBuilder) { + // TODO: SERVER-42644 Build stats (encapsulate in functions!). + if (inMongos) + resultBuilder->append("counts", + BSON("input" << 0 << "emit" << 0 << "reduce" << 0 << "output" << 0)); + + resultBuilder->append("timeMillis", 0); + + if (verbose) { + auto&& timingField = inMongos + ? BSON("shardProcessing" << 0 << "postProcessing" << 0) + : BSON("mapTime" << 0 << "emitLoop" << 0 << "reduceTime" << 0 << "total" << 0); + resultBuilder->append("timing", timingField); + } + + if (inMongos) { + resultBuilder->append( + "shardCounts", + BSON("shard-conn-string" + << BSON("input" << 0 << "emit" << 0 << "reduce" << 0 << "output" << 0))); + resultBuilder->append("postProcessCounts", + BSON("merging-shard-conn-string" + << BSON("input" << 0 << "reduce" << 0 << "output" << 0))); + } else { + resultBuilder->append("counts", + BSON("input" << 0 << "emit" << 0 << "reduce" << 0 << "output" << 0)); + } + + resultBuilder->append("ok", 1); +} + +} // namespace + +void appendInlineResponse(BSONArray&& documents, + bool verbose, + bool inMongos, + BSONObjBuilder* resultBuilder) { + resultBuilder->appendArray("results", documents); + appendMetadataFields(verbose, inMongos, resultBuilder); +} + +void appendOutResponse(NamespaceString outCollNss, + bool verbose, + bool inMongos, + BSONObjBuilder* resultBuilder) { + if (outCollNss.db().empty()) + resultBuilder->append("result", outCollNss.coll()); + else + resultBuilder->append("result", + BSON("db" << outCollNss.db() << "collection" << outCollNss.coll())); + appendMetadataFields(verbose, inMongos, resultBuilder); +} +} // namespace mongo::map_reduce_output_format diff --git a/src/mongo/db/query/map_reduce_output_format.h b/src/mongo/db/query/map_reduce_output_format.h new file mode 100644 index 00000000000..eff91ae14e3 --- /dev/null +++ b/src/mongo/db/query/map_reduce_output_format.h @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/bson/bsonobjbuilder.h" +#include "mongo/db/namespace_string.h" + +/** + * Formats Aggregation Pipeline results as legacy mapReduce output. + */ +namespace mongo::map_reduce_output_format { + +/** + * Appends fields to 'resultBuilder' as if 'documents' was a response from the mapReduce command + * with inline output. 'verbose' causes extra fields to be appended to the response in accordance + * with the verbose option on the mapReduce command. 'inMongos' indicates that we are using the + * format that was historically sent from mongos. If it isn't set, we will use the mongod format. + */ +void appendInlineResponse(BSONArray&& documents, + bool verbose, + bool inMongos, + BSONObjBuilder* resultBuilder); + +/** + * Appends fields to 'resultBuilder' to formulate a response that would be given if the mapReduce + * command had written output to the collection named by 'outCollNss'. 'verbose' causes extra fields + * to be appended to the response in accordance with the verbose option on the mapReduce command. + * 'inMongos' indicates that we are using the format that was historically sent from mongos. If it + * isn't set, we will use the mongod format. + */ +void appendOutResponse(NamespaceString outCollNss, + bool verbose, + bool inMongos, + BSONObjBuilder* resultBuilder); + +} // namespace mongo::map_reduce_output_format diff --git a/src/mongo/db/query/mr_response_formatter_test.cpp b/src/mongo/db/query/map_reduce_output_format_test.cpp index cf0bebc706a..06460770eb2 100644 --- a/src/mongo/db/query/mr_response_formatter_test.cpp +++ b/src/mongo/db/query/map_reduce_output_format_test.cpp @@ -33,25 +33,18 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/json.h" #include "mongo/db/namespace_string.h" -#include "mongo/db/query/cursor_response.h" -#include "mongo/db/query/mr_response_formatter.h" +#include "mongo/db/query/map_reduce_output_format.h" #include "mongo/unittest/unittest.h" - -// TODO: SERVER-42644 Update for processing stats from aggregation. - namespace mongo { namespace { -const NamespaceString testNss("", "mr_response_formatter"); -const NamespaceString testNssWithDb("db.mr_response_formatter"); -const CursorId testCursor(0); - -TEST(MapReduceResponseFormatter, FormatInlineMapReduceResponse) { - CursorResponse cr(testNss, testCursor, {BSON("a" << 1), BSON("b" << 1)}); - MapReduceResponseFormatter formatter(std::move(cr), boost::none, false); +TEST(MapReduceOutputFormat, FormatInlineMapReduceResponse) { + BSONArrayBuilder documents; + documents.append(BSON("a" << 1)); + documents.append(BSON("b" << 1)); BSONObjBuilder builder; - formatter.appendAsMapReduceResponse(&builder); + map_reduce_output_format::appendInlineResponse(documents.arr(), false, false, &builder); ASSERT_BSONOBJ_EQ(fromjson("{results: [{a: 1}, {b: 1}]," "timeMillis: 0," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," @@ -59,11 +52,10 @@ TEST(MapReduceResponseFormatter, FormatInlineMapReduceResponse) { builder.obj()); } -TEST(MapReduceResponseFormatter, FormatEmptyInlineMapReduceResponse) { - CursorResponse cr(testNss, testCursor, {}); - MapReduceResponseFormatter formatter(std::move(cr), boost::none, false); +TEST(MapReduceOutputFormat, FormatEmptyInlineMapReduceResponse) { + BSONArrayBuilder documents; BSONObjBuilder builder; - formatter.appendAsMapReduceResponse(&builder); + map_reduce_output_format::appendInlineResponse(documents.arr(), false, false, &builder); ASSERT_BSONOBJ_EQ(fromjson("{results: []," "timeMillis: 0," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," @@ -71,36 +63,30 @@ TEST(MapReduceResponseFormatter, FormatEmptyInlineMapReduceResponse) { builder.obj()); } -TEST(MapReduceResponseFormatter, FormatNonInlineMapReduceResponseWithoutDb) { - CursorResponse cr(testNss, testCursor, {}); - MapReduceResponseFormatter formatter(std::move(cr), testNss, false); +TEST(MapReduceOutputFormat, FormatNonInlineMapReduceResponseWithoutDb) { BSONObjBuilder builder; - formatter.appendAsMapReduceResponse(&builder); - ASSERT_BSONOBJ_EQ(fromjson("{result: \"mr_response_formatter\"," + map_reduce_output_format::appendOutResponse(NamespaceString("", "c"), false, false, &builder); + ASSERT_BSONOBJ_EQ(fromjson("{result: \"c\"," "timeMillis: 0," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," "ok: 1}"), builder.obj()); } -TEST(MapReduceResponseFormatter, FormatNonInlineMapReduceResponseWithDb) { - CursorResponse cr(testNss, testCursor, {}); - MapReduceResponseFormatter formatter(std::move(cr), testNssWithDb, false); +TEST(MapReduceOutputFormat, FormatNonInlineMapReduceResponseWithDb) { BSONObjBuilder builder; - formatter.appendAsMapReduceResponse(&builder); - ASSERT_BSONOBJ_EQ(fromjson("{result: {db: \"db\", collection: \"mr_response_formatter\"}," + map_reduce_output_format::appendOutResponse(NamespaceString("db", "c"), false, false, &builder); + ASSERT_BSONOBJ_EQ(fromjson("{result: {db: \"db\", collection: \"c\"}," "timeMillis: 0," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," "ok: 1}"), builder.obj()); } -TEST(MapReduceResponseFormatter, FormatVerboseMapReduceResponse) { - CursorResponse cr(testNss, testCursor, {}); - MapReduceResponseFormatter formatter(std::move(cr), testNss, true); +TEST(MapReduceOutputFormat, FormatVerboseMapReduceResponse) { BSONObjBuilder builder; - formatter.appendAsMapReduceResponse(&builder); - ASSERT_BSONOBJ_EQ(fromjson("{result: \"mr_response_formatter\"," + map_reduce_output_format::appendOutResponse(NamespaceString("", "c"), true, false, &builder); + ASSERT_BSONOBJ_EQ(fromjson("{result: \"c\"," "timeMillis: 0," "timing: {mapTime: 0, emitLoop: 0, reduceTime: 0, total: 0}," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," @@ -108,11 +94,12 @@ TEST(MapReduceResponseFormatter, FormatVerboseMapReduceResponse) { builder.obj()); } -TEST(MapReduceResponseFormatter, FormatInlineClusterMapReduceResponse) { - CursorResponse cr(testNss, testCursor, {BSON("a" << 1), BSON("b" << 1)}); - MapReduceResponseFormatter formatter(std::move(cr), boost::none, false); +TEST(MapReduceOutputFormat, FormatInlineClusterMapReduceResponse) { + BSONArrayBuilder documents; + documents.append(BSON("a" << 1)); + documents.append(BSON("b" << 1)); BSONObjBuilder builder; - formatter.appendAsClusterMapReduceResponse(&builder); + map_reduce_output_format::appendInlineResponse(documents.arr(), false, true, &builder); ASSERT_BSONOBJ_EQ(fromjson("{results: [{a: 1}, {b: 1}], " "counts: {input: 0, emit: 0, reduce: 0, output: 0}, " "timeMillis: 0, " @@ -124,11 +111,10 @@ TEST(MapReduceResponseFormatter, FormatInlineClusterMapReduceResponse) { builder.obj()); } -TEST(MapReduceResponseFormatter, FormatEmptyInlineClusterMapReduceResponseWithoutDb) { - CursorResponse cr(testNss, testCursor, {}); - MapReduceResponseFormatter formatter(std::move(cr), boost::none, false); +TEST(MapReduceOutputFormat, FormatEmptyInlineClusterMapReduceResponse) { + BSONArrayBuilder documents; BSONObjBuilder builder; - formatter.appendAsClusterMapReduceResponse(&builder); + map_reduce_output_format::appendInlineResponse(documents.arr(), false, true, &builder); ASSERT_BSONOBJ_EQ(fromjson("{results: []," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," "timeMillis: 0," @@ -140,12 +126,10 @@ TEST(MapReduceResponseFormatter, FormatEmptyInlineClusterMapReduceResponseWithou builder.obj()); } -TEST(MapReduceResponseFormatter, FormatNonInlineClusterMapReduceResponseWithDb) { - CursorResponse cr(testNss, testCursor, {}); - MapReduceResponseFormatter formatter(std::move(cr), testNssWithDb, false); +TEST(MapReduceOutputFormat, FormatNonInlineClusterMapReduceResponseWithoutDb) { BSONObjBuilder builder; - formatter.appendAsClusterMapReduceResponse(&builder); - ASSERT_BSONOBJ_EQ(fromjson("{result: {db: \"db\", collection: \"mr_response_formatter\"}," + map_reduce_output_format::appendOutResponse(NamespaceString("", "c"), false, true, &builder); + ASSERT_BSONOBJ_EQ(fromjson("{result: \"c\"," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," "timeMillis: 0," "shardCounts: {" @@ -156,12 +140,10 @@ TEST(MapReduceResponseFormatter, FormatNonInlineClusterMapReduceResponseWithDb) builder.obj()); } -TEST(MapReduceResponseFormatter, FormatNonInlineClusterMapReduceResponse) { - CursorResponse cr(testNss, testCursor, {}); - MapReduceResponseFormatter formatter(std::move(cr), testNss, false); +TEST(MapReduceOutputFormat, FormatNonInlineClusterMapReduceResponseWithDb) { BSONObjBuilder builder; - formatter.appendAsClusterMapReduceResponse(&builder); - ASSERT_BSONOBJ_EQ(fromjson("{result: \"mr_response_formatter\"," + map_reduce_output_format::appendOutResponse(NamespaceString("db", "c"), false, true, &builder); + ASSERT_BSONOBJ_EQ(fromjson("{result: {db: \"db\", collection: \"c\"}," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," "timeMillis: 0," "shardCounts: {" @@ -172,12 +154,10 @@ TEST(MapReduceResponseFormatter, FormatNonInlineClusterMapReduceResponse) { builder.obj()); } -TEST(MapReduceResponseFormatter, FormatVerboseClusterMapReduceResponse) { - CursorResponse cr(testNss, testCursor, {}); - MapReduceResponseFormatter formatter(std::move(cr), testNss, true); +TEST(MapReduceOutputFormat, FormatVerboseClusterMapReduceResponse) { BSONObjBuilder builder; - formatter.appendAsClusterMapReduceResponse(&builder); - ASSERT_BSONOBJ_EQ(fromjson("{result: \"mr_response_formatter\"," + map_reduce_output_format::appendOutResponse(NamespaceString("", "c"), true, true, &builder); + ASSERT_BSONOBJ_EQ(fromjson("{result: \"c\"," "counts: {input: 0, emit: 0, reduce: 0, output: 0}," "timeMillis: 0," "timing: {shardProcessing: 0, postProcessing: 0}," diff --git a/src/mongo/db/query/mr_response_formatter.cpp b/src/mongo/db/query/mr_response_formatter.cpp deleted file mode 100644 index f7b5edc95f7..00000000000 --- a/src/mongo/db/query/mr_response_formatter.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (C) 2019-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/db/query/mr_response_formatter.h" - -namespace mongo { - -MapReduceResponseFormatter::MapReduceResponseFormatter(CursorResponse aggregationResponse, - boost::optional<NamespaceString> outCollNss, - bool verbose) - : _response(std::move(aggregationResponse)), - _outCollNss(std::move(outCollNss)), - _verbose(verbose) {} - -void MapReduceResponseFormatter::appendResultsField(BSONObjBuilder* resultBuilder) { - if (_outCollNss) { - if (_outCollNss->db().empty()) { - resultBuilder->append(MapReduceResponseFormatter::kResultField, _outCollNss->coll()); - } else { - resultBuilder->append( - MapReduceResponseFormatter::kResultField, - BSON(kDbField << _outCollNss->db() << kCollectionField << _outCollNss->coll())); - } - } else { - BSONArrayBuilder docsBuilder; - auto batch = _response.releaseBatch(); - size_t sizeSoFar = 0; - for (auto& doc : batch) { - sizeSoFar += doc.objsize(); - docsBuilder.append(doc); - } - uassert(ErrorCodes::BSONObjectTooLarge, - "too much data for in memory map/reduce", - sizeSoFar < BSONObjMaxUserSize); - resultBuilder->appendArray(MapReduceResponseFormatter::kResultsField, docsBuilder.arr()); - } -} - -void MapReduceResponseFormatter::appendAsMapReduceResponse(BSONObjBuilder* resultBuilder) { - appendResultsField(resultBuilder); - // TODO: SERVER-42644 Build stats. - resultBuilder->append(kTimeMillisField, 0); - if (_verbose) { - resultBuilder->append(kTimingField, - BSON(kMapTimeField << 0 << kEmitLoopField << 0 << kReduceTimeField - << 0 << kTotalField << 0)); - } - - resultBuilder->append( - kCountsfield, - BSON(kInputField << 0 << kEmitField << 0 << kReduceField << 0 << kOutputField << 0)); - resultBuilder->append(kOkField, 1); -} - -void MapReduceResponseFormatter::appendAsClusterMapReduceResponse(BSONObjBuilder* resultBuilder) { - appendResultsField(resultBuilder); - // TODO: SERVER-42644 Build stats. - resultBuilder->append( - kCountsfield, - BSON(kInputField << 0 << kEmitField << 0 << kReduceField << 0 << kOutputField << 0)); - resultBuilder->append(kTimeMillisField, 0); - - if (_verbose) { - resultBuilder->append(kTimingField, - BSON(kShardProcessingField << 0 << kPostProcessing << 0)); - } - - resultBuilder->append( - kShardCountsfield, - BSON("shard-conn-string" << BSON(kInputField << 0 << kEmitField << 0 << kReduceField << 0 - << kOutputField << 0))); - resultBuilder->append(kPostProcessCountsField, - BSON("merging-shard-conn-string" << BSON( - kInputField << 0 << kReduceField << 0 << kOutputField << 0))); - resultBuilder->append(kOkField, 1); -} -} // namespace mongo diff --git a/src/mongo/db/query/mr_response_formatter.h b/src/mongo/db/query/mr_response_formatter.h deleted file mode 100644 index 46e5cc2d334..00000000000 --- a/src/mongo/db/query/mr_response_formatter.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (C) 2019-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/platform/basic.h" - -#include "mongo/bson/bsonobj.h" -#include "mongo/bson/bsonobjbuilder.h" -#include "mongo/db/namespace_string.h" -#include "mongo/db/query/cursor_response.h" - -namespace mongo { - -class MapReduceResponseFormatter { -public: - static constexpr StringData kResultField = "result"_sd; - static constexpr StringData kResultsField = "results"_sd; - static constexpr StringData kDbField = "db"_sd; - static constexpr StringData kCollectionField = "collection"_sd; - static constexpr StringData kTimeMillisField = "timeMillis"_sd; - static constexpr StringData kTimingField = "timing"_sd; - static constexpr StringData kMapTimeField = "mapTime"_sd; - static constexpr StringData kEmitLoopField = "emitLoop"_sd; - static constexpr StringData kReduceTimeField = "reduceTime"_sd; - static constexpr StringData kTotalField = "total"_sd; - static constexpr StringData kShardProcessingField = "shardProcessing"_sd; - static constexpr StringData kPostProcessing = "postProcessing"_sd; - static constexpr StringData kCountsfield = "counts"_sd; - static constexpr StringData kShardCountsfield = "shardCounts"_sd; - static constexpr StringData kInputField = "input"_sd; - static constexpr StringData kEmitField = "emit"_sd; - static constexpr StringData kReduceField = "reduce"_sd; - static constexpr StringData kOutputField = "output"_sd; - static constexpr StringData kPostProcessCountsField = "postProcessCounts"_sd; - static constexpr StringData kOkField = "ok"_sd; - - MapReduceResponseFormatter(CursorResponse aggregationResponse, - boost::optional<NamespaceString> outCollNss, - bool verbose); - - /* - * Appends fields to 'resultBuilder' as if '_response' were a response from the mapReduce - * command. - */ - void appendAsMapReduceResponse(BSONObjBuilder* resultBuilder); - - /** - * Appends fields to 'resultBuilder' as if '_response' were a response from the cluster - * mapReduce command. - */ - void appendAsClusterMapReduceResponse(BSONObjBuilder* resultBuilder); - -private: - CursorResponse _response; - boost::optional<NamespaceString> _outCollNss; - bool _verbose; - - /** - * Appends the 'result(s)' field to the 'resultBuilder'. - */ - void appendResultsField(BSONObjBuilder* resultBuilder); -}; -} // namespace mongo diff --git a/src/mongo/s/commands/cluster_map_reduce_agg.cpp b/src/mongo/s/commands/cluster_map_reduce_agg.cpp index 234aaef136a..af2c92807be 100644 --- a/src/mongo/s/commands/cluster_map_reduce_agg.cpp +++ b/src/mongo/s/commands/cluster_map_reduce_agg.cpp @@ -33,8 +33,8 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/commands.h" #include "mongo/db/commands/map_reduce_gen.h" +#include "mongo/db/query/cursor_response.h" #include "mongo/db/query/getmore_request.h" -#include "mongo/db/query/mr_response_formatter.h" #include "mongo/s/commands/cluster_map_reduce_agg.h" namespace mongo { @@ -81,14 +81,9 @@ bool runAggregationMapReduce(OperationContext* opCtx, auto cursorResponse = CursorResponse::parseFromBSONThrowing(aggResult); auto completeBatch = getAllAggregationResults(opCtx, dbname, cursorResponse); - CursorResponse completeCursor( + [[maybe_unused]] CursorResponse completeCursor( cursorResponse.getNSS(), cursorResponse.getCursorId(), std::move(completeBatch)); - MapReduceResponseFormatter( - std::move(completeCursor), - boost::make_optional(!inMemory, NamespaceString(std::move(outDb), std::move(outColl))), - boost::get_optional_value_or(mrRequest.getVerbose(), false)) - .appendAsClusterMapReduceResponse(&result); return true; } |