Skip to content

Commit daf0409

Browse files
streams1MongoDB Bot
authored andcommitted
SERVER-100370 Eliminate fromjson() in groupEachScore() (#31976)
GitOrigin-RevId: e844c42
1 parent ab21fc0 commit daf0409

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

src/mongo/db/pipeline/document_source_rank_fusion.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ auto setWindowFields(const auto& expCtx, const std::string& rankFieldName) {
372372
* Builds and returns an $addFields stage like this one:
373373
* {$addFields: {
374374
* prefix_scoreDetails:
375-
* [{$ifNull: [{$meta: "scoreDetails"}, {value: score, details: "Not Calculated"}]}]
375+
* {$ifNull: [{$meta: "scoreDetails"}, {value: score, details: "Not Calculated"}]}
376376
* }
377377
* }
378378
*/
@@ -463,30 +463,40 @@ auto buildFirstPipelineStages(const std::string& prefixOne,
463463
BSONObj groupEachScore(
464464
const std::map<std::string, std::unique_ptr<Pipeline, PipelineDeleter>>& pipelines,
465465
const bool includeScoreDetails) {
466-
// For each sub-pipeline, build the following string:
467-
// ", name_score: {$max: {ifNull: ["$name_score", 0]}}, name_rank: {$max: {ifNull:
468-
// ["$name_rank", 0]}}" These strings are appended to each other
469-
const auto allScores = [&]() {
470-
StringBuilder sb;
466+
// For each sub-pipeline, build the following obj:
467+
// name_score: {$max: {ifNull: ["$name_score", 0]}}
468+
// If scoreDetails is enabled, build:
469+
// name_rank: {$max: {ifNull: ["$name_rank", 0]}}
470+
// name_scoreDetails: {$mergeObjects: $name_scoreDetails}
471+
BSONObjBuilder bob;
472+
{
473+
BSONObjBuilder groupBob(bob.subobjStart("$group"_sd));
474+
groupBob.append("_id", "$docs._id");
475+
groupBob.append("docs",
476+
BSON("$first"
477+
<< "$docs"));
478+
471479
for (auto it = pipelines.begin(); it != pipelines.end(); it++) {
472-
sb << ", ";
473480
const auto& pipelineName = it->first;
474-
sb << fmt::format("{0}_score: {{$max: {{$ifNull: [\"${0}_score\", NumberLong(0)]}}}}",
475-
pipelineName);
481+
const std::string scoreName = fmt::format("{}_score", pipelineName);
482+
groupBob.append(
483+
scoreName,
484+
BSON("$max" << BSON("$ifNull" << BSON_ARRAY(fmt::format("${}", scoreName) << 0))));
476485
// We only need to preserve the rank if we're calculating score details.
477486
if (includeScoreDetails) {
478-
sb << fmt::format(
479-
", {0}_rank: {{$max: {{$ifNull: [\"${0}_rank\", NumberLong(0)]}}}}",
480-
pipelineName);
481-
sb << fmt::format(", {0}_scoreDetails: {{$mergeObjects: \"${0}_scoreDetails\"}}",
482-
pipelineName);
487+
const std::string rankName = fmt::format("{}_rank", pipelineName);
488+
groupBob.append(rankName,
489+
BSON("$max" << BSON("$ifNull" << BSON_ARRAY(
490+
fmt::format("${}", rankName) << 0))));
491+
const std::string scoreDetailsName = fmt::format("{}_scoreDetails", pipelineName);
492+
groupBob.append(scoreDetailsName,
493+
BSON("$mergeObjects" << fmt::format("${}", scoreDetailsName)));
483494
}
484495
}
485-
return sb.str();
486-
};
487-
488-
return fromjson(
489-
fmt::format("{{$group: {{_id: '$docs._id', docs: {{$first: '$docs'}}{0}}}}}", allScores()));
496+
groupBob.done();
497+
}
498+
bob.done();
499+
return bob.obj();
490500
}
491501

492502
BSONObj calculateFinalScore(

0 commit comments

Comments
 (0)