From 3c8d9f7524eb456e0a629c9f0162e4a19f0b4995 Mon Sep 17 00:00:00 2001 From: Joel Bernstein Date: Thu, 18 Jun 2015 13:27:53 +0000 Subject: [PATCH] SOLR-7689: ReRankQuery rewrite method can change the QueryResultKey causing cache misses git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1686213 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/search/ReRankQParserPlugin.java | 12 ++++- .../solr/search/TestReRankQParserPlugin.java | 54 +++++++++++++++++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/solr/core/src/java/org/apache/solr/search/ReRankQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/ReRankQParserPlugin.java index 1d975950a5b..dedf026eadb 100644 --- a/solr/core/src/java/org/apache/solr/search/ReRankQParserPlugin.java +++ b/solr/core/src/java/org/apache/solr/search/ReRankQParserPlugin.java @@ -161,8 +161,18 @@ public class ReRankQParserPlugin extends QParserPlugin { } public Query rewrite(IndexReader reader) throws IOException { - return wrap(this.mainQuery.rewrite(reader)); + Query q = mainQuery.rewrite(reader); + if(q == mainQuery) { + return this; + } else { + return clone().wrap(q); + } + } + public ReRankQuery clone() { + ReRankQuery clonedQuery = new ReRankQuery(reRankQuery, reRankDocs, reRankWeight, length); + clonedQuery.setBoost(getBoost()); + return clonedQuery; } public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException{ diff --git a/solr/core/src/test/org/apache/solr/search/TestReRankQParserPlugin.java b/solr/core/src/test/org/apache/solr/search/TestReRankQParserPlugin.java index b0a547f0683..07aa0d8ff67 100644 --- a/solr/core/src/test/org/apache/solr/search/TestReRankQParserPlugin.java +++ b/solr/core/src/test/org/apache/solr/search/TestReRankQParserPlugin.java @@ -20,6 +20,9 @@ package org.apache.solr.search; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.core.SolrInfoMBean; +import org.apache.solr.util.RefCounted; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -199,7 +202,7 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { params.add("fl", "id,score"); params.add("start", "0"); params.add("rows", "10"); - params.add("qt","/elevate"); + params.add("qt", "/elevate"); params.add("elevateIds", "1,4"); assertQ(req(params), "*[count(//doc)=6]", @@ -233,6 +236,9 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { "//result/doc[6]/float[@name='id'][.='3.0']" ); + + + params = new ModifiableSolrParams(); params.add("rq", "{!rerank reRankQuery=$rqq reRankDocs=4 reRankWeight=2}"); params.add("q", "{!edismax bq=$bqq1}*:*"); @@ -241,7 +247,7 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { params.add("fl", "id,score"); params.add("start", "0"); params.add("rows", "10"); - params.add("qt","/elevate"); + params.add("qt", "/elevate"); params.add("elevateIds", "4,1"); assertQ(req(params), "*[count(//doc)=6]", @@ -262,7 +268,7 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { params.add("fl", "id,score"); params.add("start", "4"); params.add("rows", "10"); - params.add("qt","/elevate"); + params.add("qt", "/elevate"); params.add("elevateIds", "4,1"); assertQ(req(params), "*[count(//doc)=2]", @@ -279,7 +285,7 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { params.add("fl", "id,score"); params.add("start", "4"); params.add("rows", "10"); - params.add("qt","/elevate"); + params.add("qt", "/elevate"); params.add("elevateIds", "4,1"); assertQ(req(params), "*[count(//doc)=0]"); @@ -359,7 +365,12 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { "//result/doc[5]/float[@name='id'][.='2.0']" ); + SolrInfoMBean info = h.getCore().getInfoRegistry().get("queryResultCache"); + NamedList stats = info.getStatistics(); + long inserts = (Long) stats.get("inserts"); + + assertTrue(inserts > 0); //Test range query params = new ModifiableSolrParams(); @@ -378,6 +389,39 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { "//result/doc[5]/float[@name='id'][.='1.0']" ); + + info = h.getCore().getInfoRegistry().get("queryResultCache"); + stats = info.getStatistics(); + + long inserts1 = (Long) stats.get("inserts"); + + //Last query was added to the cache + assertTrue(inserts1 > inserts); + + //Run same query and see if it was cached. This tests the query result cache hit with rewritten queries + params = new ModifiableSolrParams(); + params.add("rq", "{!rerank reRankQuery=$rqq reRankDocs=6}"); + params.add("q", "test_ti:[0 TO 2000]"); + params.add("rqq", "id:1^10 id:2^20 id:3^30 id:4^40 id:5^50 id:6^60"); + params.add("fl", "id,score"); + params.add("start", "0"); + params.add("rows", "6"); + + assertQ(req(params), "*[count(//doc)=5]", + "//result/doc[1]/float[@name='id'][.='6.0']", + "//result/doc[2]/float[@name='id'][.='5.0']", + "//result/doc[3]/float[@name='id'][.='4.0']", + "//result/doc[4]/float[@name='id'][.='2.0']", + "//result/doc[5]/float[@name='id'][.='1.0']" + ); + + info = h.getCore().getInfoRegistry().get("queryResultCache"); + stats = info.getStatistics(); + long inserts2 = (Long) stats.get("inserts"); + //Last query was NOT added to the cache + assertTrue(inserts1 == inserts2); + + //Test range query embedded in larger query params = new ModifiableSolrParams(); params.add("rq", "{!rerank reRankQuery=$rqq reRankDocs=6}"); @@ -411,6 +455,7 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { "//result/doc[2]/float[@name='id'][.='1.0']" ); + //Test ReRankDocs > docs returned params = new ModifiableSolrParams(); @@ -540,4 +585,5 @@ public class TestReRankQParserPlugin extends SolrTestCaseJ4 { assertTrue(e.code() == SolrException.ErrorCode.BAD_REQUEST.code); } } + }