From ac73b0ca2bbdf8aa5ef6227898a32778a8189dfa Mon Sep 17 00:00:00 2001 From: iverase Date: Tue, 28 Aug 2018 11:26:15 +0200 Subject: [PATCH 1/5] =?UTF-8?q?Profiler:=20Don=E2=80=99t=20profile=20NEXTD?= =?UTF-8?q?OC=20for=20ConstantScoreQuery.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A ConstantScore query will return the iterator of its inner query. However, when profiling, the constant score query is wrapped separately from its inner query, which distorts the times emitted by the profiler. Return the iterator directly in such a case. Closes #23430 --- .../search/profile/query/ProfileScorer.java | 4 ++ .../profile/query/QueryProfilerTests.java | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java b/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java index 66e0e0fe77cfe..6168b1dc9d2e5 100644 --- a/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java +++ b/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java @@ -19,6 +19,7 @@ package org.elasticsearch.search.profile.query; +import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.TwoPhaseIterator; @@ -75,6 +76,9 @@ public Collection getChildren() throws IOException { @Override public DocIdSetIterator iterator() { + if (profileWeight.getQuery() instanceof ConstantScoreQuery) { + return scorer.iterator(); + } final DocIdSetIterator in = scorer.iterator(); return new DocIdSetIterator() { diff --git a/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java b/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java index 5e10292fa3e7c..9acfee84dda37 100644 --- a/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java +++ b/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java @@ -28,6 +28,7 @@ import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; +import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.Explanation; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.LeafCollector; @@ -117,6 +118,49 @@ public void testBasic() throws IOException { assertThat(rewriteTime, greaterThan(0L)); } + public void testConstantScoreQuery() throws IOException { + QueryProfiler profiler = new QueryProfiler(); + searcher.setProfiler(profiler); + Query query = new ConstantScoreQuery(new TermQuery(new Term("foo", "bar"))); + searcher.search(query, 1); + List results = profiler.getTree(); + assertEquals(1, results.size()); + Map breakdownConstantScoreQuery = results.get(0).getTimeBreakdown(); + assertEquals(1, results.get(0).getProfiledChildren().size()); + Map breakdownTermQuery = results.get(0).getProfiledChildren().get(0).getTimeBreakdown(); + + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + + assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + + assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + + long rewriteTime = profiler.getRewriteTime(); + assertThat(rewriteTime, greaterThan(0L)); + } + public void testNoScoring() throws IOException { QueryProfiler profiler = new QueryProfiler(); searcher.setProfiler(profiler); From 8060960f87eb476209bcd90779523f54e758f65c Mon Sep 17 00:00:00 2001 From: iverase Date: Tue, 18 Sep 2018 09:11:28 +0200 Subject: [PATCH 2/5] Override timings for constant score queries with timing of the underlying iterator when it is not cached --- .../profile/AbstractProfileBreakdown.java | 4 ++ .../search/profile/query/ProfileScorer.java | 20 +++++- .../profile/query/QueryProfilerTests.java | 70 ++++++++++++++++++- 3 files changed, 91 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/search/profile/AbstractProfileBreakdown.java b/server/src/main/java/org/elasticsearch/search/profile/AbstractProfileBreakdown.java index f49ad4a8718a0..654c67af444ea 100644 --- a/server/src/main/java/org/elasticsearch/search/profile/AbstractProfileBreakdown.java +++ b/server/src/main/java/org/elasticsearch/search/profile/AbstractProfileBreakdown.java @@ -49,6 +49,10 @@ public Timer getTimer(T timing) { return timings[timing.ordinal()]; } + public void setTimer(T timing, Timer timer) { + timings[timing.ordinal()] = timer; + } + /** Convert this record to a map from timingType to times. */ public Map toTimingMap() { Map map = new HashMap<>(); diff --git a/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java b/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java index 6168b1dc9d2e5..ed4de59a12b5c 100644 --- a/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java +++ b/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java @@ -38,6 +38,7 @@ final class ProfileScorer extends Scorer { private final Scorer scorer; private ProfileWeight profileWeight; private final Timer scoreTimer, nextDocTimer, advanceTimer, matchTimer; + private final boolean isConstantScoreQuery; ProfileScorer(ProfileWeight w, Scorer scorer, QueryProfileBreakdown profile) throws IOException { super(w); @@ -47,6 +48,20 @@ final class ProfileScorer extends Scorer { nextDocTimer = profile.getTimer(QueryTimingType.NEXT_DOC); advanceTimer = profile.getTimer(QueryTimingType.ADVANCE); matchTimer = profile.getTimer(QueryTimingType.MATCH); + ProfileScorer profileScorer = null; + if (w.getQuery() instanceof ConstantScoreQuery && scorer instanceof ProfileScorer) { + profileScorer = (ProfileScorer) scorer; + } else if (w.getQuery() instanceof ConstantScoreQuery && scorer.getChildren().size() == 1) { + profileScorer = (ProfileScorer) scorer.getChildren().iterator().next().child; + } + if (profileScorer != null) { + isConstantScoreQuery = true; + profile.setTimer(QueryTimingType.NEXT_DOC, profileScorer.nextDocTimer); + profile.setTimer(QueryTimingType.ADVANCE, profileScorer.advanceTimer); + profile.setTimer(QueryTimingType.MATCH, profileScorer.matchTimer); + } else { + isConstantScoreQuery = false; + } } @Override @@ -76,7 +91,7 @@ public Collection getChildren() throws IOException { @Override public DocIdSetIterator iterator() { - if (profileWeight.getQuery() instanceof ConstantScoreQuery) { + if (isConstantScoreQuery) { return scorer.iterator(); } final DocIdSetIterator in = scorer.iterator(); @@ -116,6 +131,9 @@ public long cost() { @Override public TwoPhaseIterator twoPhaseIterator() { + if (isConstantScoreQuery) { + return scorer.twoPhaseIterator(); + } final TwoPhaseIterator in = scorer.twoPhaseIterator(); if (in == null) { return null; diff --git a/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java b/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java index 9acfee84dda37..d31cb90146fb7 100644 --- a/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java +++ b/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java @@ -131,14 +131,14 @@ public void testConstantScoreQuery() throws IOException { assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); - assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString()).longValue(), greaterThan(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); - assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), greaterThan(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); @@ -157,10 +157,76 @@ public void testConstantScoreQuery() throws IOException { assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + assertEquals(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue()); + + long rewriteTime = profiler.getRewriteTime(); + assertThat(rewriteTime, greaterThan(0L)); + } + + public void testConstantScoreTotalHitsQuery() throws IOException { + Query query = new ConstantScoreQuery(new TermQuery(new Term("foo", "bar"))); + + QueryProfiler profiler = new QueryProfiler(); + searcher.setProfiler(profiler); + TotalHitCountCollector collector = new TotalHitCountCollector(); + searcher.search(query, collector); + + List results = profiler.getTree(); + assertEquals(1, results.size()); + Map breakdownConstantScoreQuery = results.get(0).getTimeBreakdown(); + assertEquals(1, results.get(0).getProfiledChildren().size()); + Map breakdownTermQuery = results.get(0).getProfiledChildren().get(0).getTimeBreakdown(); + + boolean cache = breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue() ==0; + + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + + assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); + if (cache) { + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), equalTo(0L)); + } else { + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); + } + + assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); + if (cache) { + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), equalTo(0L)); + } else { + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); + } + assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + + if (cache == false) { + assertEquals(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue()); + } + long rewriteTime = profiler.getRewriteTime(); assertThat(rewriteTime, greaterThan(0L)); + } + public void testNoScoring() throws IOException { QueryProfiler profiler = new QueryProfiler(); searcher.setProfiler(profiler); From 2875de0c64294faca067f6d78d5646fde2acc606 Mon Sep 17 00:00:00 2001 From: iverase Date: Tue, 18 Sep 2018 10:15:30 +0200 Subject: [PATCH 3/5] fix forbidden API errors --- .../search/profile/query/QueryProfilerTests.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java b/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java index 1a6c1052c7ea8..cb2f987d68f47 100644 --- a/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java +++ b/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java @@ -158,7 +158,8 @@ public void testConstantScoreQuery() throws IOException { assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); - assertEquals(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue()); + assertEquals(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), + breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue()); long rewriteTime = profiler.getRewriteTime(); assertThat(rewriteTime, greaterThan(0L)); @@ -219,7 +220,8 @@ public void testConstantScoreTotalHitsQuery() throws IOException { assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); if (cache == false) { - assertEquals(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue()); + assertEquals(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), + breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue()); } long rewriteTime = profiler.getRewriteTime(); From f2b07713b3329f6cb6b76122b00ec5f4a899ab5a Mon Sep 17 00:00:00 2001 From: iverase Date: Tue, 18 Sep 2018 10:39:00 +0200 Subject: [PATCH 4/5] explain logic to find child scorer and make code safer by adding an instanceof check --- .../search/profile/query/ProfileScorer.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java b/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java index 0dd1b31873270..ab8fb5dbcae02 100644 --- a/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java +++ b/server/src/main/java/org/elasticsearch/search/profile/query/ProfileScorer.java @@ -21,6 +21,7 @@ import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.DocIdSetIterator; +import org.apache.lucene.search.Scorable; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.TwoPhaseIterator; import org.apache.lucene.search.Weight; @@ -54,9 +55,15 @@ final class ProfileScorer extends Scorer { computeMaxScoreTimer = profile.getTimer(QueryTimingType.COMPUTE_MAX_SCORE); ProfileScorer profileScorer = null; if (w.getQuery() instanceof ConstantScoreQuery && scorer instanceof ProfileScorer) { + //Case when we have a totalHits query and it is not cached profileScorer = (ProfileScorer) scorer; } else if (w.getQuery() instanceof ConstantScoreQuery && scorer.getChildren().size() == 1) { - profileScorer = (ProfileScorer) scorer.getChildren().iterator().next().child; + //Case when we have a top N query. If the scorer has no children, it is because it is cached + //and in that case we do not do any special treatment + Scorable childScorer = scorer.getChildren().iterator().next().child; + if (childScorer instanceof ProfileScorer) { + profileScorer = (ProfileScorer) childScorer; + } } if (profileScorer != null) { isConstantScoreQuery = true; From 88c8bcad2ed5f79510b3aa960045a29021913725 Mon Sep 17 00:00:00 2001 From: iverase Date: Tue, 18 Sep 2018 14:52:17 +0200 Subject: [PATCH 5/5] add test that shows the different situations we can have with cached queries --- .../profile/query/QueryProfilerTests.java | 160 +++++++++++++++--- 1 file changed, 139 insertions(+), 21 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java b/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java index cb2f987d68f47..ba58a79953be1 100644 --- a/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java +++ b/server/src/test/java/org/elasticsearch/search/profile/query/QueryProfilerTests.java @@ -33,6 +33,7 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.LeafCollector; import org.apache.lucene.search.Query; +import org.apache.lucene.search.QueryCachingPolicy; import org.apache.lucene.search.RandomApproximationQuery; import org.apache.lucene.search.ScoreMode; import org.apache.lucene.search.Scorer; @@ -165,8 +166,11 @@ public void testConstantScoreQuery() throws IOException { assertThat(rewriteTime, greaterThan(0L)); } - public void testConstantScoreTotalHitsQuery() throws IOException { + public void testConstantScoreTotalHitsBeingCachedQuery() throws IOException { Query query = new ConstantScoreQuery(new TermQuery(new Term("foo", "bar"))); + //clean cache and make sure queries will be cached + searcher.setQueryCache(IndexSearcher.getDefaultQueryCache()); + searcher.setQueryCachingPolicy(ALWAYS_CACHE_POLICY); QueryProfiler profiler = new QueryProfiler(); searcher.setProfiler(profiler); @@ -178,9 +182,7 @@ public void testConstantScoreTotalHitsQuery() throws IOException { Map breakdownConstantScoreQuery = results.get(0).getTimeBreakdown(); assertEquals(1, results.get(0).getProfiledChildren().size()); Map breakdownTermQuery = results.get(0).getProfiledChildren().get(0).getTimeBreakdown(); - - boolean cache = breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue() ==0; - + //In this case scorers for constant score query and term query are disconnected. assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); @@ -196,37 +198,128 @@ public void testConstantScoreTotalHitsQuery() throws IOException { assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); - if (cache) { - assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), equalTo(0L)); - assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), equalTo(0L)); - } else { - assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); - assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); - } + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + + assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + long rewriteTime = profiler.getRewriteTime(); + assertThat(rewriteTime, greaterThan(0L)); + } + + public void testConstantScoreTotalHitsNotCachedQuery() throws IOException { + Query query = new ConstantScoreQuery(new TermQuery(new Term("foo", "bar"))); + + //clean cache and make sure queries will not be cached + searcher.setQueryCache(IndexSearcher.getDefaultQueryCache()); + searcher.setQueryCachingPolicy(NEVER_CACHE_POLICY); + + QueryProfiler profiler = new QueryProfiler(); + searcher.setProfiler(profiler); + TotalHitCountCollector collector = new TotalHitCountCollector(); + searcher.search(query, collector); + + List results = profiler.getTree(); + assertEquals(1, results.size()); + Map breakdownConstantScoreQuery = results.get(0).getTimeBreakdown(); + assertEquals(1, results.get(0).getProfiledChildren().size()); + Map breakdownTermQuery = results.get(0).getProfiledChildren().get(0).getTimeBreakdown(); + //Timing from the scorer of term query are inherited by constant score query scorer. + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString()).longValue(), equalTo(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); - if (cache) { - assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), equalTo(0L)); - assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), equalTo(0L)); - } else { - assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); - assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); - } + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); - if (cache == false) { - assertEquals(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), + + assertEquals(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue()); - } + long rewriteTime = profiler.getRewriteTime(); assertThat(rewriteTime, greaterThan(0L)); + } + public void testConstantScoreTotalHitsCachedQuery() throws IOException { + Query query = new ConstantScoreQuery(new TermQuery(new Term("foo", "bar"))); + + //clean cache and make sure queries will be cached + searcher.setQueryCache(IndexSearcher.getDefaultQueryCache()); + searcher.setQueryCachingPolicy(ALWAYS_CACHE_POLICY); + //Put query on cache + TotalHitCountCollector collector = new TotalHitCountCollector(); + searcher.search(query, collector); + + QueryProfiler profiler = new QueryProfiler(); + searcher.setProfiler(profiler); + collector = new TotalHitCountCollector(); + searcher.search(query, collector); + + List results = profiler.getTree(); + assertEquals(1, results.size()); + Map breakdownConstantScoreQuery = results.get(0).getTimeBreakdown(); + assertEquals(1, results.get(0).getProfiledChildren().size()); + Map breakdownTermQuery = results.get(0).getProfiledChildren().get(0).getTimeBreakdown(); + + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownConstantScoreQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + + assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString()).longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString()).longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString()).longValue(), equalTo(0L)); + + assertThat(breakdownTermQuery.get(QueryTimingType.CREATE_WEIGHT.toString() + "_count").longValue(), greaterThan(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.BUILD_SCORER.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.NEXT_DOC.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.ADVANCE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.SCORE.toString() + "_count").longValue(), equalTo(0L)); + assertThat(breakdownTermQuery.get(QueryTimingType.MATCH.toString() + "_count").longValue(), equalTo(0L)); + + long rewriteTime = profiler.getRewriteTime(); + assertThat(rewriteTime, greaterThan(0L)); } @@ -388,4 +481,29 @@ public void testScorerSupplier() throws IOException { reader.close(); dir.close(); } + + private static final QueryCachingPolicy ALWAYS_CACHE_POLICY = new QueryCachingPolicy() { + + @Override + public void onUse(Query query) {} + + @Override + public boolean shouldCache(Query query) throws IOException { + return true; + } + + }; + + private static final QueryCachingPolicy NEVER_CACHE_POLICY = new QueryCachingPolicy() { + + @Override + public void onUse(Query query) {} + + @Override + public boolean shouldCache(Query query) throws IOException { + return false; + } + + }; + }