1919
2020package org .elasticsearch .search .profile .query ;
2121
22+ import org .apache .lucene .search .ConstantScoreQuery ;
2223import org .apache .lucene .search .DocIdSetIterator ;
24+ import org .apache .lucene .search .Scorable ;
2325import org .apache .lucene .search .Scorer ;
2426import org .apache .lucene .search .TwoPhaseIterator ;
2527import org .apache .lucene .search .Weight ;
@@ -36,7 +38,10 @@ final class ProfileScorer extends Scorer {
3638
3739 private final Scorer scorer ;
3840 private ProfileWeight profileWeight ;
41+
3942 private final Timer scoreTimer , nextDocTimer , advanceTimer , matchTimer , shallowAdvanceTimer , computeMaxScoreTimer ;
43+ private final boolean isConstantScoreQuery ;
44+
4045
4146 ProfileScorer (ProfileWeight w , Scorer scorer , QueryProfileBreakdown profile ) throws IOException {
4247 super (w );
@@ -48,6 +53,26 @@ final class ProfileScorer extends Scorer {
4853 matchTimer = profile .getTimer (QueryTimingType .MATCH );
4954 shallowAdvanceTimer = profile .getTimer (QueryTimingType .SHALLOW_ADVANCE );
5055 computeMaxScoreTimer = profile .getTimer (QueryTimingType .COMPUTE_MAX_SCORE );
56+ ProfileScorer profileScorer = null ;
57+ if (w .getQuery () instanceof ConstantScoreQuery && scorer instanceof ProfileScorer ) {
58+ //Case when we have a totalHits query and it is not cached
59+ profileScorer = (ProfileScorer ) scorer ;
60+ } else if (w .getQuery () instanceof ConstantScoreQuery && scorer .getChildren ().size () == 1 ) {
61+ //Case when we have a top N query. If the scorer has no children, it is because it is cached
62+ //and in that case we do not do any special treatment
63+ Scorable childScorer = scorer .getChildren ().iterator ().next ().child ;
64+ if (childScorer instanceof ProfileScorer ) {
65+ profileScorer = (ProfileScorer ) childScorer ;
66+ }
67+ }
68+ if (profileScorer != null ) {
69+ isConstantScoreQuery = true ;
70+ profile .setTimer (QueryTimingType .NEXT_DOC , profileScorer .nextDocTimer );
71+ profile .setTimer (QueryTimingType .ADVANCE , profileScorer .advanceTimer );
72+ profile .setTimer (QueryTimingType .MATCH , profileScorer .matchTimer );
73+ } else {
74+ isConstantScoreQuery = false ;
75+ }
5176 }
5277
5378 @ Override
@@ -77,6 +102,9 @@ public Collection<ChildScorable> getChildren() throws IOException {
77102
78103 @ Override
79104 public DocIdSetIterator iterator () {
105+ if (isConstantScoreQuery ) {
106+ return scorer .iterator ();
107+ }
80108 final DocIdSetIterator in = scorer .iterator ();
81109 return new DocIdSetIterator () {
82110
@@ -114,6 +142,9 @@ public long cost() {
114142
115143 @ Override
116144 public TwoPhaseIterator twoPhaseIterator () {
145+ if (isConstantScoreQuery ) {
146+ return scorer .twoPhaseIterator ();
147+ }
117148 final TwoPhaseIterator in = scorer .twoPhaseIterator ();
118149 if (in == null ) {
119150 return null ;
0 commit comments