diff --git a/solr/core/src/java/org/apache/solr/handler/component/MergeStrategy.java b/solr/core/src/java/org/apache/solr/handler/component/MergeStrategy.java
index 0ff19bd523e..8c3483be422 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/MergeStrategy.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/MergeStrategy.java
@@ -23,8 +23,10 @@ import java.util.Comparator;
import java.io.IOException;
/**
- * The MergeStrategy class defines custom merge logic for distributed searches.
- **/
+* The MergeStrategy class defines custom merge logic for distributed searches.
+*
+* Note: This API is experimental and may change in non backward-compatible ways in the future
+**/
public interface MergeStrategy {
diff --git a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
index ac2689b9d17..83a55afc38c 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
@@ -151,17 +151,28 @@ public class QueryComponent extends SearchComponent
q = new BooleanQuery();
}
- if(q instanceof RankQuery) {
- MergeStrategy mergeStrategy = ((RankQuery)q).getMergeStrategy();
- if(mergeStrategy != null) {
- rb.addMergeStrategy(mergeStrategy);
- if(mergeStrategy.handlesMergeFields()) {
- rb.mergeFieldHandler = mergeStrategy;
+ rb.setQuery( q );
+
+
+ String rankQueryString = rb.req.getParams().get(CommonParams.RQ);
+ if(rankQueryString != null) {
+ QParser rqparser = QParser.getParser(rankQueryString, defType, req);
+ Query rq = rqparser.getQuery();
+ if(rq instanceof RankQuery) {
+ RankQuery rankQuery = (RankQuery)rq;
+ rb.setQuery(rankQuery.wrap(q)); //Wrap the RankQuery around the main query.
+ MergeStrategy mergeStrategy = rankQuery.getMergeStrategy();
+ if(mergeStrategy != null) {
+ rb.addMergeStrategy(mergeStrategy);
+ if(mergeStrategy.handlesMergeFields()) {
+ rb.mergeFieldHandler = mergeStrategy;
+ }
}
+ } else {
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,"rq parameter must be a RankQuery");
}
}
- rb.setQuery( q );
rb.setSortSpec( parser.getSort(true) );
rb.setQparser(parser);
diff --git a/solr/core/src/java/org/apache/solr/search/RankQuery.java b/solr/core/src/java/org/apache/solr/search/RankQuery.java
index da8c00a1387..86ee49a11cb 100644
--- a/solr/core/src/java/org/apache/solr/search/RankQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/RankQuery.java
@@ -17,13 +17,21 @@
package org.apache.solr.search;
+import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TopDocsCollector;
import org.apache.lucene.search.Query;
import org.apache.solr.handler.component.MergeStrategy;
+import java.io.IOException;
+
+/**
+ * Note: This API is experimental and may change in non backward-compatible ways in the future
+ **/
+
public abstract class RankQuery extends Query {
- public abstract TopDocsCollector getTopDocsCollector(int len, SolrIndexSearcher.QueryCommand cmd);
+ public abstract TopDocsCollector getTopDocsCollector(int len, SolrIndexSearcher.QueryCommand cmd, IndexSearcher searcher) throws IOException;
public abstract MergeStrategy getMergeStrategy();
+ public abstract RankQuery wrap(Query mainQuery);
}
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 50e82bf352d..44a5e89b47e 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -1503,7 +1503,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable,SolrIn
Query q = cmd.getQuery();
if(q instanceof RankQuery) {
RankQuery rq = (RankQuery)q;
- return rq.getTopDocsCollector(len, cmd);
+ return rq.getTopDocsCollector(len, cmd, this);
}
if (null == cmd.getSort()) {
diff --git a/solr/core/src/test/org/apache/solr/search/MergeStrategyTest.java b/solr/core/src/test/org/apache/solr/search/MergeStrategyTest.java
index 68b8c9e8a7d..19bc9f0056d 100644
--- a/solr/core/src/test/org/apache/solr/search/MergeStrategyTest.java
+++ b/solr/core/src/test/org/apache/solr/search/MergeStrategyTest.java
@@ -80,18 +80,18 @@ public class MergeStrategyTest extends BaseDistributedSearchTestCase {
handle.put("_version_", SKIP);
//Test mergeStrategy that uses score
- query("q", "{!rank q=$qq}", "qq", "*:*", "rows","12", "sort", "sort_i asc", "fl","*,score");
+ query("rq", "{!rank}", "q", "*:*", "rows","12", "sort", "sort_i asc", "fl","*,score");
//Test without mergeStrategy
query("q", "*:*", "rows","12", "sort", "sort_i asc");
//Test mergeStrategy1 that uses a sort field.
- query("q", "{!rank mergeStrategy=1 q=$qq}", "qq", "*:*", "rows","12", "sort", "sort_i asc");
+ query("rq", "{!rank mergeStrategy=1}", "q", "*:*", "rows","12", "sort", "sort_i asc");
ModifiableSolrParams params = new ModifiableSolrParams();
- params.add("qq", "*:*");
+ params.add("q", "*:*");
params.add("rows", "12");
- params.add("q", "{!rank q=$qq}");
+ params.add("rq", "{!rank}");
params.add("sort", "sort_i asc");
params.add("fl","*,score");
setDistributedParams(params);
diff --git a/solr/core/src/test/org/apache/solr/search/RankQueryTest.java b/solr/core/src/test/org/apache/solr/search/RankQueryTest.java
index 8f749861907..c98e62ba575 100644
--- a/solr/core/src/test/org/apache/solr/search/RankQueryTest.java
+++ b/solr/core/src/test/org/apache/solr/search/RankQueryTest.java
@@ -70,8 +70,8 @@ public class RankQueryTest extends SolrTestCaseJ4 {
ModifiableSolrParams params = new ModifiableSolrParams();
- params.add("qq", "*:*");
- params.add("q", "{!rank q=$qq}");
+ params.add("q", "*:*");
+ params.add("rq", "{!rank}");
params.add("sort","sort_i asc");
assertQ(req(params), "*[count(//doc)=6]",
@@ -84,9 +84,9 @@ public class RankQueryTest extends SolrTestCaseJ4 {
);
params = new ModifiableSolrParams();
- params.add("qq", "{!edismax bf=$bff}*:*");
+ params.add("q", "{!edismax bf=$bff}*:*");
params.add("bff", "field(sort_i)");
- params.add("q", "{!rank q=$qq collector=1}");
+ params.add("rq", "{!rank collector=1}");
assertQ(req(params), "*[count(//doc)=6]",
"//result/doc[6]/str[@name='id'][.='4']",
diff --git a/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java b/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java
index 267b7e923f4..cea0185daa1 100644
--- a/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java
+++ b/solr/core/src/test/org/apache/solr/search/TestRankQueryPlugin.java
@@ -85,12 +85,10 @@ public class TestRankQueryPlugin extends QParserPlugin {
}
public Query parse() throws SyntaxError {
- String qs = localParams.get("q");
- QParser parser = QParser.getParser(qs, null, req);
- Query q = parser.getQuery();
+
int mergeStrategy = localParams.getInt("mergeStrategy", 0);
int collector = localParams.getInt("collector", 0);
- return new TestRankQuery(collector, mergeStrategy, q);
+ return new TestRankQuery(collector, mergeStrategy);
}
}
@@ -134,13 +132,17 @@ public class TestRankQueryPlugin extends QParserPlugin {
return q.toString(field);
}
- public TestRankQuery(int collector, int mergeStrategy, Query q) {
+ public RankQuery wrap(Query q) {
this.q = q;
+ return this;
+ }
+
+ public TestRankQuery(int collector, int mergeStrategy) {
this.collector = collector;
this.mergeStrategy = mergeStrategy;
}
- public TopDocsCollector getTopDocsCollector(int len, SolrIndexSearcher.QueryCommand cmd) {
+ public TopDocsCollector getTopDocsCollector(int len, SolrIndexSearcher.QueryCommand cmd, IndexSearcher searcher) {
if(collector == 0)
return new TestCollector(null);
else
diff --git a/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java b/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
index 4256abe60a7..0f122c54fbd 100644
--- a/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
+++ b/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
@@ -47,6 +47,9 @@ public interface CommonParams {
/** query string */
public static final String Q ="q";
+
+ /** rank query */
+ public static final String RQ ="rq";
/** distrib string */
public static final String DISTRIB = "distrib";