@@ -372,7 +372,7 @@ auto setWindowFields(const auto& expCtx, const std::string& rankFieldName) {
372
372
* Builds and returns an $addFields stage like this one:
373
373
* {$addFields: {
374
374
* prefix_scoreDetails:
375
- * [ {$ifNull: [{$meta: "scoreDetails"}, {value: score, details: "Not Calculated"}]}]
375
+ * {$ifNull: [{$meta: "scoreDetails"}, {value: score, details: "Not Calculated"}]}
376
376
* }
377
377
* }
378
378
*/
@@ -463,30 +463,40 @@ auto buildFirstPipelineStages(const std::string& prefixOne,
463
463
BSONObj groupEachScore (
464
464
const std::map<std::string, std::unique_ptr<Pipeline, PipelineDeleter>>& pipelines,
465
465
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
+
471
479
for (auto it = pipelines.begin (); it != pipelines.end (); it++) {
472
- sb << " , " ;
473
480
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 ))));
476
485
// We only need to preserve the rank if we're calculating score details.
477
486
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)));
483
494
}
484
495
}
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 ();
490
500
}
491
501
492
502
BSONObj calculateFinalScore (
0 commit comments