2020import org .elasticsearch .search .builder .SearchSourceBuilder ;
2121import org .elasticsearch .search .dfs .AggregatedDfs ;
2222import org .elasticsearch .search .internal .ShardSearchContextId ;
23+ import org .elasticsearch .search .rank .RankDoc ;
2324import org .elasticsearch .search .rank .context .RankFeaturePhaseRankCoordinatorContext ;
2425import org .elasticsearch .search .rank .feature .RankFeatureDoc ;
2526import org .elasticsearch .search .rank .feature .RankFeatureResult ;
@@ -187,7 +188,7 @@ private void onPhaseDone(
187188 new ActionListener <>() {
188189 @ Override
189190 public void onResponse (RankFeatureDoc [] docsWithUpdatedScores ) {
190- RankFeatureDoc [] topResults = rankFeaturePhaseRankCoordinatorContext .rankAndPaginate (docsWithUpdatedScores , true );
191+ RankDoc [] topResults = rankFeaturePhaseRankCoordinatorContext .rankAndPaginate (docsWithUpdatedScores , true );
191192 SearchPhaseController .ReducedQueryPhase reducedRankFeaturePhase = newReducedQueryPhaseResults (
192193 reducedQueryPhase ,
193194 topResults
@@ -200,13 +201,18 @@ public void onFailure(Exception e) {
200201 if (rankFeaturePhaseRankCoordinatorContext .failuresAllowed ()) {
201202 // TODO: handle the exception somewhere
202203 // don't want to log the entire stack trace, it's not helpful here
203- logger .warn ("Exception computing updated ranks: {}. Continuing with existing ranks. " , e .toString ());
204+ logger .warn ("Exception computing updated ranks, continuing with existing ranks: {} " , e .toString ());
204205 // use the existing score docs as-is
205- RankFeatureDoc [] existingScores = Arrays .stream (reducedQueryPhase .sortedTopDocs ().scoreDocs ())
206- .map (sd -> new RankFeatureDoc (sd .doc , sd .score , sd .shardIndex ))
207- .toArray (RankFeatureDoc []::new );
208-
209- RankFeatureDoc [] topResults = rankFeaturePhaseRankCoordinatorContext .rankAndPaginate (existingScores , false );
206+ // downstream things expect every doc to have a score, so we need to infer a score here
207+ // if the doc doesn't otherwise have a score. We can use the rank.
208+ ScoreDoc [] inputDocs = reducedQueryPhase .sortedTopDocs ().scoreDocs ();
209+ // use RankDoc to indicate there was a problem using the specified features
210+ RankFeatureDoc [] rankDocs = new RankFeatureDoc [inputDocs .length ];
211+ for (int i = 0 ; i < inputDocs .length ; i ++) {
212+ ScoreDoc doc = inputDocs [i ];
213+ rankDocs [i ] = new RankFeatureDoc (doc .doc , Float .isNaN (doc .score ) ? 1f / (i +1 ) : doc .score , doc .shardIndex );
214+ }
215+ RankDoc [] topResults = rankFeaturePhaseRankCoordinatorContext .rankAndPaginate (rankDocs , false );
210216 SearchPhaseController .ReducedQueryPhase reducedRankFeaturePhase = newReducedQueryPhaseResults (
211217 reducedQueryPhase ,
212218 topResults
0 commit comments