Skip to content

Commit dc629bb

Browse files
wbuerger46MongoDB Bot
authored andcommitted
SERVER-100373: Replace fromjson in calculateFinalScoreDetails() (#31983)
GitOrigin-RevId: 7254b10
1 parent 9a8cf8b commit dc629bb

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

src/mongo/db/pipeline/document_source_rank_fusion.cpp

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -518,29 +518,43 @@ BSONObj calculateFinalScore(
518518
return BSON("$addFields" << BSON("score" << allInputs()));
519519
}
520520

521-
BSONObj calculateFinalScoreDetails(
522-
const std::map<std::string, std::unique_ptr<Pipeline, PipelineDeleter>>& inputs) {
523-
// Generate the following string for each pipeline:
524-
// "name: {rank: $name_rank, details: $name_scoreDetails}""
525-
// And add them all to an array to be merged together.
526-
BSONObjBuilder bob;
527-
BSONArrayBuilder mergeNamedDetailsBob(bob.subarrayStart("$mergeObjects"_sd));
528-
for (auto it = inputs.begin(); it != inputs.end(); it++) {
529-
mergeNamedDetailsBob.append(fromjson(
530-
fmt::format("{{{0}: {{$mergeObjects: [{{rank: '${0}_rank'}}, '${0}_scoreDetails']}}}}",
531-
it->first)));
532-
}
533-
mergeNamedDetailsBob.done();
521+
boost::intrusive_ptr<DocumentSource> calculateFinalScoreDetails(
522+
const std::map<std::string, std::unique_ptr<Pipeline, PipelineDeleter>>& inputs,
523+
const boost::intrusive_ptr<ExpressionContext>& expCtx) {
534524
// Create the following object:
535525
/*
536526
{ $addFields: {
537527
calculatedScoreDetails: {
538-
$mergeObjects: [<generated above>]
528+
$mergeObjects: [
529+
name1: {
530+
$mergeObjects: [{"rank" << "$name1_rank"}, "$name1_scoreDetails"]
531+
},
532+
name2: {
533+
$mergeObjects: [{"rank" << "$name2_rank"}, "$name2_scoreDetails"]
534+
},
535+
...
536+
]
539537
}
540538
}
541539
*/
542-
return fromjson(
543-
fmt::format("{{$addFields: {{calculatedScoreDetails: {0}}}}}", bob.obj().toString()));
540+
BSONObjBuilder bob;
541+
BSONArrayBuilder topLevelMergeNamedDetailsBob(bob.subarrayStart("$mergeObjects"_sd));
542+
for (auto it = inputs.begin(); it != inputs.end(); it++) {
543+
const std::string rankFieldName = fmt::format("${}_rank", it->first);
544+
const std::string scoreDetailsFieldName = fmt::format("${}_scoreDetails", it->first);
545+
topLevelMergeNamedDetailsBob.append(
546+
BSON(it->first << BSON("$mergeObjects"_sd << BSON_ARRAY(BSON("rank"_sd << rankFieldName)
547+
<< scoreDetailsFieldName))));
548+
}
549+
topLevelMergeNamedDetailsBob.done();
550+
551+
boost::intrusive_ptr<Expression> mergeObjectsExpr =
552+
ExpressionFromAccumulator<AccumulatorMergeObjects>::parse(
553+
expCtx.get(), bob.obj().firstElement(), expCtx->variablesParseState);
554+
555+
auto addFields = DocumentSourceAddFields::create(
556+
"calculatedScoreDetails"_sd, std::move(mergeObjectsExpr), expCtx.get());
557+
return addFields;
544558
}
545559

546560
boost::intrusive_ptr<DocumentSource> buildUnionWithPipeline(
@@ -589,8 +603,8 @@ std::list<boost::intrusive_ptr<DocumentSource>> buildScoreAndMergeStages(
589603
SbeCompatibility::noRequirements);
590604

591605
if (includeScoreDetails) {
592-
auto addFieldsDetails = DocumentSourceAddFields::createFromBson(
593-
calculateFinalScoreDetails(inputPipelines).firstElement(), expCtx);
606+
boost::intrusive_ptr<DocumentSource> addFieldsDetails =
607+
calculateFinalScoreDetails(inputPipelines, expCtx);
594608
auto setDetails = DocumentSourceSetMetadata::create(
595609
expCtx,
596610
Expression::parseObject(expCtx.get(),

0 commit comments

Comments
 (0)