You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2014/01/10 17:59:24 UTC
svn commit: r1557196 - in /lucene/dev/branches/branch_4x: ./ dev-tools/
lucene/ lucene/analysis/
lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/
lucene/analysis/icu/src/java/org/apache/lucene/collation/ lucene/backwards/
luce...
Author: hossman
Date: Fri Jan 10 16:59:22 2014
New Revision: 1557196
URL: http://svn.apache.org/r1557196
Log:
SOLR-5463: new 'cursorMark' request param for deep paging of sorted result sets (merge r1556036 and r1557192)
Added:
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/CursorMark.java
- copied unchanged from r1556036, lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/CursorMark.java
lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/schema-sorts.xml
- copied unchanged from r1556036, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/schema-sorts.xml
lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/solrconfig-deeppaging.xml
- copied unchanged from r1556036, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-deeppaging.xml
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/CursorPagingTest.java
- copied, changed from r1556036, lucene/dev/trunk/solr/core/src/test/org/apache/solr/CursorPagingTest.java
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/TestCursorMarkWithoutUniqueKey.java
- copied unchanged from r1556036, lucene/dev/trunk/solr/core/src/test/org/apache/solr/TestCursorMarkWithoutUniqueKey.java
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/DistribCursorPagingTest.java
- copied unchanged from r1556036, lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/DistribCursorPagingTest.java
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/search/CursorMarkTest.java
- copied unchanged from r1556036, lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/CursorMarkTest.java
lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CursorMarkParams.java
- copied unchanged from r1556036, lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CursorMarkParams.java
Modified:
lucene/dev/branches/branch_4x/ (props changed)
lucene/dev/branches/branch_4x/dev-tools/ (props changed)
lucene/dev/branches/branch_4x/lucene/ (props changed)
lucene/dev/branches/branch_4x/lucene/BUILD.txt (props changed)
lucene/dev/branches/branch_4x/lucene/CHANGES.txt (props changed)
lucene/dev/branches/branch_4x/lucene/JRE_VERSION_MIGRATION.txt (props changed)
lucene/dev/branches/branch_4x/lucene/LICENSE.txt (props changed)
lucene/dev/branches/branch_4x/lucene/MIGRATE.txt (props changed)
lucene/dev/branches/branch_4x/lucene/NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/lucene/README.txt (props changed)
lucene/dev/branches/branch_4x/lucene/SYSTEM_REQUIREMENTS.txt (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/ (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/ASCIITLD.jflex-macro (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/SUPPLEMENTARY.jflex-macro (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/StandardTokenizerImpl40.java (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/StandardTokenizerImpl40.jflex (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/UAX29URLEmailTokenizerImpl40.java (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/UAX29URLEmailTokenizerImpl40.jflex (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/std40/package.html (props changed)
lucene/dev/branches/branch_4x/lucene/analysis/icu/src/java/org/apache/lucene/collation/ICUCollationKeyFilterFactory.java (props changed)
lucene/dev/branches/branch_4x/lucene/backwards/ (props changed)
lucene/dev/branches/branch_4x/lucene/benchmark/ (props changed)
lucene/dev/branches/branch_4x/lucene/build.xml (props changed)
lucene/dev/branches/branch_4x/lucene/classification/ (props changed)
lucene/dev/branches/branch_4x/lucene/classification/build.xml (props changed)
lucene/dev/branches/branch_4x/lucene/classification/ivy.xml (props changed)
lucene/dev/branches/branch_4x/lucene/classification/src/ (props changed)
lucene/dev/branches/branch_4x/lucene/codecs/ (props changed)
lucene/dev/branches/branch_4x/lucene/common-build.xml (props changed)
lucene/dev/branches/branch_4x/lucene/core/ (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/index.40.cfs.zip (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/index.40.nocfs.zip (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/index.40.optimized.cfs.zip (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/index/index.40.optimized.nocfs.zip (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestSort.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestSortDocValues.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java (props changed)
lucene/dev/branches/branch_4x/lucene/core/src/test/org/apache/lucene/search/TestTotalHitCountCollector.java (props changed)
lucene/dev/branches/branch_4x/lucene/demo/ (props changed)
lucene/dev/branches/branch_4x/lucene/expressions/ (props changed)
lucene/dev/branches/branch_4x/lucene/facet/ (props changed)
lucene/dev/branches/branch_4x/lucene/grouping/ (props changed)
lucene/dev/branches/branch_4x/lucene/highlighter/ (props changed)
lucene/dev/branches/branch_4x/lucene/ivy-settings.xml (props changed)
lucene/dev/branches/branch_4x/lucene/ivy-versions.properties (props changed)
lucene/dev/branches/branch_4x/lucene/join/ (props changed)
lucene/dev/branches/branch_4x/lucene/licenses/ (props changed)
lucene/dev/branches/branch_4x/lucene/memory/ (props changed)
lucene/dev/branches/branch_4x/lucene/misc/ (props changed)
lucene/dev/branches/branch_4x/lucene/module-build.xml (props changed)
lucene/dev/branches/branch_4x/lucene/queries/ (props changed)
lucene/dev/branches/branch_4x/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionQuerySort.java (props changed)
lucene/dev/branches/branch_4x/lucene/queryparser/ (props changed)
lucene/dev/branches/branch_4x/lucene/replicator/ (props changed)
lucene/dev/branches/branch_4x/lucene/sandbox/ (props changed)
lucene/dev/branches/branch_4x/lucene/site/ (props changed)
lucene/dev/branches/branch_4x/lucene/spatial/ (props changed)
lucene/dev/branches/branch_4x/lucene/suggest/ (props changed)
lucene/dev/branches/branch_4x/lucene/test-framework/ (props changed)
lucene/dev/branches/branch_4x/lucene/tools/ (props changed)
lucene/dev/branches/branch_4x/solr/ (props changed)
lucene/dev/branches/branch_4x/solr/CHANGES.txt
lucene/dev/branches/branch_4x/solr/LICENSE.txt (props changed)
lucene/dev/branches/branch_4x/solr/NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/solr/README.txt (props changed)
lucene/dev/branches/branch_4x/solr/SYSTEM_REQUIREMENTS.txt (props changed)
lucene/dev/branches/branch_4x/solr/build.xml (props changed)
lucene/dev/branches/branch_4x/solr/cloud-dev/ (props changed)
lucene/dev/branches/branch_4x/solr/common-build.xml (props changed)
lucene/dev/branches/branch_4x/solr/contrib/ (props changed)
lucene/dev/branches/branch_4x/solr/core/ (props changed)
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/QParser.java
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestConfig.java (props changed)
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java
lucene/dev/branches/branch_4x/solr/example/ (props changed)
lucene/dev/branches/branch_4x/solr/licenses/ (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpclient-LICENSE-ASL.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpclient-NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpcore-LICENSE-ASL.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpcore-NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpmime-LICENSE-ASL.txt (props changed)
lucene/dev/branches/branch_4x/solr/licenses/httpmime-NOTICE.txt (props changed)
lucene/dev/branches/branch_4x/solr/scripts/ (props changed)
lucene/dev/branches/branch_4x/solr/site/ (props changed)
lucene/dev/branches/branch_4x/solr/solrj/ (props changed)
lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
lucene/dev/branches/branch_4x/solr/test-framework/ (props changed)
lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
lucene/dev/branches/branch_4x/solr/webapp/ (props changed)
Modified: lucene/dev/branches/branch_4x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/CHANGES.txt?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/solr/CHANGES.txt Fri Jan 10 16:59:22 2014
@@ -103,6 +103,9 @@ New Features
* SOLR-5541: Allow QueryElevationComponent to accept elevateIds and excludeIds
as http parameters (Joel Bernstein)
+* SOLR-5463: new 'cursorMark' request param for deep paging of sorted result sets
+ (sarowe, hossman)
+
Bug Fixes
----------------------
Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java Fri Jan 10 16:59:22 2014
@@ -17,8 +17,6 @@
package org.apache.solr.handler.component;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.StringField;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.ReaderUtil;
@@ -33,12 +31,12 @@ import org.apache.lucene.search.grouping
import org.apache.lucene.search.grouping.SearchGroup;
import org.apache.lucene.search.grouping.TopGroups;
import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.CharsRef;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.*;
+import org.apache.solr.common.params.CursorMarkParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.StrUtils;
@@ -48,6 +46,7 @@ import org.apache.solr.response.SolrQuer
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
+import org.apache.solr.search.CursorMark;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocList;
import org.apache.solr.search.DocListAndSet;
@@ -82,6 +81,8 @@ import org.apache.solr.search.grouping.e
import org.apache.solr.search.grouping.endresulttransformer.SimpleEndResultTransformer;
import org.apache.solr.util.SolrPluginUtils;
+import org.apache.commons.lang.StringUtils;
+
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -147,8 +148,15 @@ public class QueryComponent extends Sear
rb.setQuery( q );
rb.setSortSpec( parser.getSort(true) );
rb.setQparser(parser);
- rb.setScoreDoc(parser.getPaging());
+ final String cursorStr = rb.req.getParams().get(CursorMarkParams.CURSOR_MARK_PARAM);
+ if (null != cursorStr) {
+ final CursorMark cursorMark = new CursorMark(rb.req.getSchema(),
+ rb.getSortSpec());
+ cursorMark.parseSerializedTotem(cursorStr);
+ rb.setCursorMark(cursorMark);
+ }
+
String[] fqs = req.getParams().getParams(CommonParams.FQ);
if (fqs!=null && fqs.length!=0) {
List<Query> filters = rb.getFilters();
@@ -171,11 +179,23 @@ public class QueryComponent extends Sear
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
}
- boolean grouping = params.getBool(GroupParams.GROUP, false);
- if (!grouping) {
- return;
+ if (params.getBool(GroupParams.GROUP, false)) {
+ prepareGrouping(rb);
}
+ }
+
+ private void prepareGrouping(ResponseBuilder rb) throws IOException {
+
+ SolrQueryRequest req = rb.req;
+ SolrParams params = req.getParams();
+ if (null != rb.getCursorMark()) {
+ // It's hard to imagine, conceptually, what it would mean to combine
+ // grouping with a cursor - so for now we just don't allow the combination at all
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can not use Grouping with " +
+ CursorMarkParams.CURSOR_MARK_PARAM);
+ }
+
SolrIndexSearcher.QueryCommand cmd = rb.getQueryCommand();
SolrIndexSearcher searcher = rb.req.getSearcher();
GroupingSpecification groupingSpec = new GroupingSpecification();
@@ -242,6 +262,11 @@ public class QueryComponent extends Sear
// -1 as flag if not set.
long timeAllowed = (long)params.getInt( CommonParams.TIME_ALLOWED, -1 );
+ if (null != rb.getCursorMark() && 0 < timeAllowed) {
+ // fundementally incompatible
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can not search using both " +
+ CursorMarkParams.CURSOR_MARK_PARAM + " and " + CommonParams.TIME_ALLOWED);
+ }
// Optional: This could also be implemented by the top-level searcher sending
// a filter that lists the ids... that would be transparent to
@@ -434,13 +459,18 @@ public class QueryComponent extends Sear
searcher.search(result,cmd);
rb.setResult( result );
-
ResultContext ctx = new ResultContext();
ctx.docs = rb.getResults().docList;
ctx.query = rb.getQuery();
rsp.add("response", ctx);
rsp.getToLog().add("hits", rb.getResults().docList.matches());
+ if ( ! rb.req.getParams().getBool(ShardParams.IS_SHARD,false) ) {
+ if (null != rb.getNextCursorMark()) {
+ rb.rsp.add(CursorMarkParams.CURSOR_MARK_NEXT,
+ rb.getNextCursorMark().getSerializedTotem());
+ }
+ }
doFieldSortValues(rb, searcher);
doPrefetch(rb);
}
@@ -452,6 +482,8 @@ public class QueryComponent extends Sear
// The query cache doesn't currently store sort field values, and SolrIndexSearcher doesn't
// currently have an option to return sort field values. Because of this, we
// take the documents given and re-derive the sort values.
+ //
+ // TODO: See SOLR-5595
boolean fsv = req.getParams().getBool(ResponseBuilder.FIELD_SORT_VALUES,false);
if(fsv){
NamedList<Object[]> sortVals = new NamedList<Object[]>(); // order is important for the sort fields
@@ -696,6 +728,10 @@ public class QueryComponent extends Sear
}
rb.rsp.add("response", rb._responseDocs);
+ if (null != rb.getNextCursorMark()) {
+ rb.rsp.add(CursorMarkParams.CURSOR_MARK_NEXT,
+ rb.getNextCursorMark().getSerializedTotem());
+ }
}
private void createDistributedIdf(ResponseBuilder rb) {
@@ -904,11 +940,66 @@ public class QueryComponent extends Sear
// TODO: use ResponseBuilder (w/ comments) or the request context?
rb.resultIds = resultIds;
rb._responseDocs = responseDocs;
+
+ populateNextCursorMarkFromMergedShards(rb);
+
if (partialResults) {
rb.rsp.getResponseHeader().add( "partialResults", Boolean.TRUE );
}
}
+ /**
+ * Inspects the state of the {@link ResponseBuilder} and populates the next
+ * {@link ResponseBuilder#setNextCursorMark} as appropriate based on the merged
+ * sort values from individual shards
+ *
+ * @param rb A <code>ResponseBuilder</code> that already contains merged
+ * <code>ShardDocs</code> in <code>resultIds</code>, may or may not be
+ * part of a Cursor based request (method will NOOP if not needed)
+ */
+ private void populateNextCursorMarkFromMergedShards(ResponseBuilder rb) {
+
+ final CursorMark lastCursorMark = rb.getCursorMark();
+ if (null == lastCursorMark) {
+ // Not a cursor based request
+ return; // NOOP
+ }
+
+ assert null != rb.resultIds : "resultIds was not set in ResponseBuilder";
+
+ Collection<ShardDoc> docsOnThisPage = rb.resultIds.values();
+
+ if (0 == docsOnThisPage.size()) {
+ // nothing more matching query, re-use existing totem so user can "resume"
+ // search later if it makes sense for this sort.
+ rb.setNextCursorMark(lastCursorMark);
+ return;
+ }
+
+ ShardDoc lastDoc = null;
+ // ShardDoc and rb.resultIds are weird structures to work with...
+ for (ShardDoc eachDoc : docsOnThisPage) {
+ if (null == lastDoc || lastDoc.positionInResponse < eachDoc.positionInResponse) {
+ lastDoc = eachDoc;
+ }
+ }
+ SortField[] sortFields = lastCursorMark.getSortSpec().getSort().getSort();
+ List<Object> nextCursorMarkValues = new ArrayList<Object>(sortFields.length);
+ for (SortField sf : sortFields) {
+ if (sf.getType().equals(SortField.Type.SCORE)) {
+ assert null != lastDoc.score : "lastDoc has null score";
+ nextCursorMarkValues.add(lastDoc.score);
+ } else {
+ assert null != sf.getField() : "SortField has null field";
+ List<Object> fieldVals = (List<Object>) lastDoc.sortFieldValues.get(sf.getField());
+ nextCursorMarkValues.add(fieldVals.get(lastDoc.orderInShard));
+ }
+ }
+ CursorMark nextCursorMark = lastCursorMark.createNext(nextCursorMarkValues);
+ assert null != nextCursorMark : "null nextCursorMark";
+ rb.setNextCursorMark(nextCursorMark);
+ }
+
private NamedList unmarshalSortValues(SortSpec sortSpec,
NamedList sortFieldValues,
IndexSchema schema) {
@@ -982,6 +1073,7 @@ public class QueryComponent extends Sear
// no need for a sort, we already have order
sreq.params.remove(CommonParams.SORT);
+ sreq.params.remove(CursorMarkParams.CURSOR_MARK_PARAM);
// we already have the field sort values
sreq.params.remove(ResponseBuilder.FIELD_SORT_VALUES);
Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/component/ResponseBuilder.java Fri Jan 10 16:59:22 2014
@@ -18,7 +18,6 @@
package org.apache.solr.handler.component;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.grouping.SearchGroup;
import org.apache.lucene.search.grouping.TopGroups;
import org.apache.lucene.util.BytesRef;
@@ -30,6 +29,7 @@ import org.apache.solr.common.util.Simpl
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.search.CursorMark;
import org.apache.solr.search.DocListAndSet;
import org.apache.solr.search.QParser;
import org.apache.solr.search.SolrIndexSearcher;
@@ -70,9 +70,8 @@ public class ResponseBuilder
private List<Query> filters = null;
private SortSpec sortSpec = null;
private GroupingSpecification groupingSpec;
- //used for handling deep paging
- private ScoreDoc scoreDoc;
-
+ private CursorMark cursorMark;
+ private CursorMark nextCursorMark;
private DocListAndSet results = null;
private NamedList<Object> debugInfo = null;
@@ -395,7 +394,7 @@ public class ResponseBuilder
.setLen(getSortSpec().getCount())
.setFlags(getFieldFlags())
.setNeedDocSet(isNeedDocSet())
- .setScoreDoc(getScoreDoc()); //Issue 1726
+ .setCursorMark(getCursorMark());
return cmd;
}
@@ -407,6 +406,10 @@ public class ResponseBuilder
if (result.isPartialResults()) {
rsp.getResponseHeader().add("partialResults", Boolean.TRUE);
}
+ if (null != cursorMark) {
+ assert null != result.getNextCursorMark() : "using cursor but no next cursor set";
+ this.setNextCursorMark(result.getNextCursorMark());
+ }
}
public long getNumberDocumentsFound() {
@@ -416,13 +419,17 @@ public class ResponseBuilder
return _responseDocs.getNumFound();
}
- public ScoreDoc getScoreDoc()
- {
- return scoreDoc;
+ public CursorMark getCursorMark() {
+ return cursorMark;
}
-
- public void setScoreDoc(ScoreDoc scoreDoc)
- {
- this.scoreDoc = scoreDoc;
+ public void setCursorMark(CursorMark cursorMark) {
+ this.cursorMark = cursorMark;
+ }
+
+ public CursorMark getNextCursorMark() {
+ return nextCursorMark;
+ }
+ public void setNextCursorMark(CursorMark nextCursorMark) {
+ this.nextCursorMark = nextCursorMark;
}
}
Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/QParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/QParser.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/QParser.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/QParser.java Fri Jan 10 16:59:22 2014
@@ -17,7 +17,6 @@
package org.apache.solr.search;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc; //Issue 1726
import org.apache.lucene.search.Sort;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.MapSolrParams;
@@ -209,37 +208,6 @@ public abstract class QParser {
}
/**
- * use common params to look up pageScore and pageDoc in global params
- * @return the ScoreDoc
- */
- public ScoreDoc getPaging() throws SyntaxError
- {
- return null;
-
- /*** This is not ready for prime-time... see SOLR-1726
-
- String pageScoreS = null;
- String pageDocS = null;
-
- pageScoreS = params.get(CommonParams.PAGESCORE);
- pageDocS = params.get(CommonParams.PAGEDOC);
-
- if (pageScoreS == null || pageDocS == null)
- return null;
-
- int pageDoc = pageDocS != null ? Integer.parseInt(pageDocS) : -1;
- float pageScore = pageScoreS != null ? new Float(pageScoreS) : -1;
- if(pageDoc != -1 && pageScore != -1){
- return new ScoreDoc(pageDoc, pageScore);
- }
- else {
- return null;
- }
-
- ***/
- }
-
- /**
* @param useGlobalParams look up sort, start, rows in global params if not in local params
* @return the sort specification
*/
Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java Fri Jan 10 16:59:22 2014
@@ -69,6 +69,7 @@ import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.FieldDoc;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Sort;
@@ -76,6 +77,7 @@ import org.apache.lucene.search.SortFiel
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TimeLimitingCollector;
import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.search.TopFieldDocs;
import org.apache.lucene.search.TopDocsCollector;
import org.apache.lucene.search.TopFieldCollector;
import org.apache.lucene.search.TopScoreDocCollector;
@@ -1345,6 +1347,7 @@ public class SolrIndexSearcher extends I
key = null; // we won't be caching the result
}
}
+ cmd.setSupersetMaxDoc(supersetMaxDoc);
// OK, so now we need to generate an answer.
@@ -1367,7 +1370,6 @@ public class SolrIndexSearcher extends I
}
}
- // disable useFilterCache optimization temporarily
if (useFilterCache) {
// now actually use the filter cache.
// for large filters that match few documents, this may be
@@ -1380,11 +1382,9 @@ public class SolrIndexSearcher extends I
// todo: there could be a sortDocSet that could take a list of
// the filters instead of anding them first...
// perhaps there should be a multi-docset-iterator
- superset = sortDocSet(out.docSet,cmd.getSort(),supersetMaxDoc);
- out.docList = superset.subset(cmd.getOffset(),cmd.getLen());
+ sortDocSet(qr, cmd);
} else {
// do it the normal way...
- cmd.setSupersetMaxDoc(supersetMaxDoc);
if ((flags & GET_DOCSET)!=0) {
// this currently conflates returning the docset for the base query vs
// the base query and all filters.
@@ -1393,11 +1393,28 @@ public class SolrIndexSearcher extends I
if (qDocSet!=null && filterCache!=null && !qr.isPartialResults()) filterCache.put(cmd.getQuery(),qDocSet);
} else {
getDocListNC(qr,cmd);
- //Parameters: cmd.getQuery(),theFilt,cmd.getSort(),0,supersetMaxDoc,cmd.getFlags(),cmd.getTimeAllowed(),responseHeader);
}
+ assert null != out.docList : "docList is null";
+ }
+ if (null == cmd.getCursorMark()) {
+ // Kludge...
+ // we can't use DocSlice.subset, even though it should be an identity op
+ // because it gets confused by situations where there are lots of matches, but
+ // less docs in the slice then were requested, (due to the cursor)
+ // so we have to short circuit the call.
+ // None of which is really a problem since we can't use caching with
+ // cursors anyway, but it still looks weird to have to special case this
+ // behavior based on this condition - hence the long explanation.
superset = out.docList;
out.docList = superset.subset(cmd.getOffset(),cmd.getLen());
+ } else {
+ // sanity check our cursor assumptions
+ assert null == superset : "cursor: superset isn't null";
+ assert 0 == cmd.getOffset() : "cursor: command offset mismatch";
+ assert 0 == out.docList.offset() : "cursor: docList offset mismatch";
+ assert cmd.getLen() >= supersetMaxDoc : "cursor: superset len mismatch: " +
+ cmd.getLen() + " vs " + supersetMaxDoc;
}
// lastly, put the superset in the cache if the size is less than or equal
@@ -1407,7 +1424,76 @@ public class SolrIndexSearcher extends I
}
}
+ /**
+ * Helper method for extracting the {@link FieldDoc} sort values from a
+ * {@link TopFieldDocs} when available and making the appropriate call to
+ * {@link QueryResult#setNextCursorMark} when applicable.
+ *
+ * @param qr <code>QueryResult</code> to modify
+ * @param qc <code>QueryCommand</code> for context of method
+ * @param topDocs May or may not be a <code>TopFieldDocs</code>
+ */
+ private void populateNextCursorMarkFromTopDocs(QueryResult qr, QueryCommand qc,
+ TopDocs topDocs) {
+ // TODO: would be nice to rename & generalize this method for non-cursor cases...
+ // ...would be handy to reuse the ScoreDoc/FieldDoc sort vals directly in distrib sort
+ // ...but that has non-trivial queryResultCache implications
+ // See: SOLR-5595
+
+ if (null == qc.getCursorMark()) {
+ // nothing to do, short circuit out
+ return;
+ }
+ final CursorMark lastCursorMark = qc.getCursorMark();
+
+ // if we have a cursor, then we have a sort that at minimum involves uniqueKey..
+ // so we must have a TopFieldDocs containing FieldDoc[]
+ assert topDocs instanceof TopFieldDocs : "TopFieldDocs cursor constraint violated";
+ final TopFieldDocs topFieldDocs = (TopFieldDocs) topDocs;
+ final ScoreDoc[] scoreDocs = topFieldDocs.scoreDocs;
+
+ if (0 == scoreDocs.length) {
+ // no docs on this page, re-use existing cursor mark
+ qr.setNextCursorMark(lastCursorMark);
+ } else {
+ ScoreDoc lastDoc = scoreDocs[scoreDocs.length-1];
+ assert lastDoc instanceof FieldDoc : "FieldDoc cursor constraint violated";
+
+ List<Object> lastFields = Arrays.<Object>asList(((FieldDoc)lastDoc).fields);
+ CursorMark nextCursorMark = lastCursorMark.createNext(lastFields);
+ assert null != nextCursorMark : "null nextCursorMark";
+ qr.setNextCursorMark(nextCursorMark);
+ }
+ }
+
+ /**
+ * Helper method for inspecting QueryCommand and creating the appropriate
+ * {@link TopDocsCollector}
+ *
+ * @param len the number of docs to return
+ * @param cmd The Command whose properties should determine the type of
+ * TopDocsCollector to use.
+ */
+ private TopDocsCollector buildTopDocsCollector(int len, QueryCommand cmd) throws IOException {
+
+ if (null == cmd.getSort()) {
+ assert null == cmd.getCursorMark() : "have cursor but no sort";
+ return TopScoreDocCollector.create(len, true);
+ } else {
+ // we have a sort
+ final boolean needScores = (cmd.getFlags() & GET_SCORES) != 0;
+ final Sort weightedSort = weightSort(cmd.getSort());
+ final CursorMark cursor = cmd.getCursorMark();
+
+ // :TODO: make fillFields it's own QueryCommand flag? ...
+ // ... see comments in populateNextCursorMarkFromTopDocs for cache issues (SOLR-5595)
+ final boolean fillFields = (null != cursor);
+ final FieldDoc searchAfter = (null != cursor ? cursor.getSearchAfterFieldDoc() : null);
+ return TopFieldCollector.create(weightedSort, len, searchAfter,
+ fillFields, needScores, needScores, true);
+ }
+ }
private void getDocListNC(QueryResult qr,QueryCommand cmd) throws IOException {
final long timeAllowed = cmd.getTimeAllowed();
@@ -1502,18 +1588,10 @@ public class SolrIndexSearcher extends I
scores = new float[nDocsReturned];
totalHits = numHits[0];
maxScore = totalHits>0 ? topscore[0] : 0.0f;
+ // no docs on this page, so cursor doesn't change
+ qr.setNextCursorMark(cmd.getCursorMark());
} else {
- TopDocsCollector topCollector;
- if (cmd.getSort() == null) {
- if(cmd.getScoreDoc() != null) {
- topCollector = TopScoreDocCollector.create(len, cmd.getScoreDoc(), true); //create the Collector with InOrderPagingCollector
- } else {
- topCollector = TopScoreDocCollector.create(len, true);
- }
-
- } else {
- topCollector = TopFieldCollector.create(weightSort(cmd.getSort()), len, false, needScores, needScores, true);
- }
+ final TopDocsCollector topCollector = buildTopDocsCollector(len, cmd);
Collector collector = topCollector;
if (terminateEarly) {
collector = new EarlyTerminatingCollector(collector, cmd.len);
@@ -1538,6 +1616,8 @@ public class SolrIndexSearcher extends I
totalHits = topCollector.getTotalHits();
TopDocs topDocs = topCollector.topDocs(0, len);
+ populateNextCursorMarkFromTopDocs(qr, cmd, topDocs);
+
maxScore = totalHits>0 ? topDocs.getMaxScore() : 0.0f;
nDocsReturned = topDocs.scoreDocs.length;
ids = new int[nDocsReturned];
@@ -1638,16 +1718,11 @@ public class SolrIndexSearcher extends I
scores = new float[nDocsReturned];
totalHits = set.size();
maxScore = totalHits>0 ? topscore[0] : 0.0f;
+ // no docs on this page, so cursor doesn't change
+ qr.setNextCursorMark(cmd.getCursorMark());
} else {
- TopDocsCollector topCollector;
-
- if (cmd.getSort() == null) {
- topCollector = TopScoreDocCollector.create(len, true);
- } else {
- topCollector = TopFieldCollector.create(weightSort(cmd.getSort()), len, false, needScores, needScores, true);
- }
-
+ final TopDocsCollector topCollector = buildTopDocsCollector(len, cmd);
DocSetCollector setCollector = new DocSetDelegateCollector(maxDoc>>6, maxDoc, topCollector);
Collector collector = setCollector;
if (terminateEarly) {
@@ -1677,6 +1752,7 @@ public class SolrIndexSearcher extends I
assert(totalHits == set.size());
TopDocs topDocs = topCollector.topDocs(0, len);
+ populateNextCursorMarkFromTopDocs(qr, cmd, topDocs);
maxScore = totalHits>0 ? topDocs.getMaxScore() : 0.0f;
nDocsReturned = topDocs.scoreDocs.length;
@@ -1925,16 +2001,21 @@ public class SolrIndexSearcher extends I
return qr.getDocListAndSet();
}
- protected DocList sortDocSet(DocSet set, Sort sort, int nDocs) throws IOException {
+ protected void sortDocSet(QueryResult qr, QueryCommand cmd) throws IOException {
+ DocSet set = qr.getDocListAndSet().docSet;
+ int nDocs = cmd.getSupersetMaxDoc();
if (nDocs == 0) {
// SOLR-2923
- return new DocSlice(0, 0, new int[0], null, 0, 0f);
+ qr.getDocListAndSet().docList = new DocSlice(0, 0, new int[0], null, set.size(), 0f);
+ qr.setNextCursorMark(cmd.getCursorMark());
+ return;
}
+
// bit of a hack to tell if a set is sorted - do it better in the future.
boolean inOrder = set instanceof BitDocSet || set instanceof SortedIntDocSet;
- TopDocsCollector topCollector = TopFieldCollector.create(weightSort(sort), nDocs, false, false, false, inOrder);
+ TopDocsCollector topCollector = buildTopDocsCollector(nDocs, cmd);
DocIterator iter = set.iterator();
int base=0;
@@ -1963,7 +2044,8 @@ public class SolrIndexSearcher extends I
ids[i] = scoreDoc.doc;
}
- return new DocSlice(0,nDocsReturned,ids,null,topDocs.totalHits,0.0f);
+ qr.getDocListAndSet().docList = new DocSlice(0,nDocsReturned,ids,null,topDocs.totalHits,0.0f);
+ populateNextCursorMarkFromTopDocs(qr, cmd, topDocs);
}
@@ -2187,20 +2269,27 @@ public class SolrIndexSearcher extends I
private int supersetMaxDoc;
private int flags;
private long timeAllowed = -1;
- //Issue 1726 start
- private ScoreDoc scoreDoc;
+ private CursorMark cursorMark;
- public ScoreDoc getScoreDoc()
- {
- return scoreDoc;
+ public CursorMark getCursorMark() {
+ return cursorMark;
}
- public void setScoreDoc(ScoreDoc scoreDoc)
- {
- this.scoreDoc = scoreDoc;
+ public QueryCommand setCursorMark(CursorMark cursorMark) {
+ this.cursorMark = cursorMark;
+ if (null != cursorMark) {
+ // If we're using a cursor then we can't allow queryResult caching because the
+ // cache keys don't know anything about the collector used.
+ //
+ // in theory, we could enhance the cache keys to be aware of the searchAfter
+ // FieldDoc but then there would still be complexity around things like the cache
+ // window size that would need to be worked out
+ //
+ // we *can* however allow the use of checking the filterCache for non-score based
+ // sorts, because that still runs our paging collector over the entire DocSet
+ this.flags |= (NO_CHECK_QCACHE | NO_SET_QCACHE);
+ }
+ return this;
}
- //Issue 1726 end
-
- // public List<Grouping.Command> groupCommands;
public Query getQuery() { return query; }
public QueryCommand setQuery(Query query) {
@@ -2309,6 +2398,7 @@ public class SolrIndexSearcher extends I
public static class QueryResult {
private boolean partialResults;
private DocListAndSet docListAndSet;
+ private CursorMark nextCursorMark;
public Object groupedResults; // TODO: currently for testing
@@ -2333,6 +2423,13 @@ public class SolrIndexSearcher extends I
public void setDocListAndSet( DocListAndSet listSet ) { docListAndSet = listSet; }
public DocListAndSet getDocListAndSet() { return docListAndSet; }
+
+ public void setNextCursorMark(CursorMark next) {
+ this.nextCursorMark = next;
+ }
+ public CursorMark getNextCursorMark() {
+ return nextCursorMark;
+ }
}
}
Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java Fri Jan 10 16:59:22 2014
@@ -948,51 +948,6 @@ public class BasicFunctionalityTest exte
}
}
- @Ignore("See SOLR-1726")
- @Test
- public void testDeepPaging() throws Exception {
- for (int i = 0; i < 1000; i++){
- assertU(adoc("id", String.valueOf(i), "foo_t", English.intToEnglish(i)));
- }
- assertU(commit());
- SolrQueryRequest goldReq = null;
- try {
- goldReq = req("q", "foo_t:one", "rows", "50", "fl", "docid, score");
- SolrQueryResponse gold = h.queryAndResponse("standard", goldReq);
- ResultContext response = (ResultContext) gold.getValues().get("response");
- assertQ("page: " + 0 + " failed",
- req("q", "foo_t:one", "rows", "10", CommonParams.QT, "standard", "fl", "[docid], score"),
- "*[count(//doc)=10]");
- //ugh, what a painful way to get the document
- DocIterator iterator = response.docs.subset(9, 1).iterator();
- int lastDoc = iterator.nextDoc();
- float lastScore = iterator.score();
- for (int i = 1; i < 5; i++){
- //page through some results
- DocList subset = response.docs.subset(i * 10, 1);
- iterator = subset.iterator();
- int compareDoc = iterator.nextDoc();
- float compareScore = iterator.score();
- assertQ("page: " + i + " failed",
- req("q", "foo_t:one", CommonParams.QT, "standard", "fl", "[docid], score",
- "start", String.valueOf(i * 10), "rows", "1", //only get one doc, and then compare it to gold
- CommonParams.PAGEDOC, String.valueOf(lastDoc), CommonParams.PAGESCORE, String.valueOf(lastScore)),
- "*[count(//doc)=1]",
- "//float[@name='score'][.='" + compareScore + "']",
- "//int[@name='[docid]'][.='" + compareDoc + "']"
- );
- lastScore = compareScore;
- lastDoc = compareDoc;
-
- }
- } finally {
- if (goldReq != null ) {
- goldReq.close();
- }
- }
- }
-
-
// /** this doesn't work, but if it did, this is how we'd test it. */
// public void testOverwriteFalse() {
Copied: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/CursorPagingTest.java (from r1556036, lucene/dev/trunk/solr/core/src/test/org/apache/solr/CursorPagingTest.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/CursorPagingTest.java?p2=lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/CursorPagingTest.java&p1=lucene/dev/trunk/solr/core/src/test/org/apache/solr/CursorPagingTest.java&r1=1556036&r2=1557196&rev=1557196&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/CursorPagingTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/CursorPagingTest.java Fri Jan 10 16:59:22 2014
@@ -679,7 +679,7 @@ public class CursorPagingTest extends So
}
if (useField()) {
- int numBytes = (int) skewed(_TestUtil.nextInt(random(), 20, 50), 2);
+ int numBytes = (Integer) skewed(_TestUtil.nextInt(random(), 20, 50), 2);
byte[] randBytes = new byte[numBytes];
random().nextBytes(randBytes);
doc.addField("bin", ByteBuffer.wrap(randBytes));
Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/schema/SortableBinaryField.java Fri Jan 10 16:59:22 2014
@@ -40,10 +40,7 @@ public class SortableBinaryField extends
@Override
public void checkSchemaField(final SchemaField field) {
- if (field.hasDocValues() && !field.multiValued() && !(field.isRequired() || field.getDefaultValue() != null)) {
- throw new IllegalStateException(
- "Field " + this + " has single-valued doc values enabled, but has no default value and is not required");
- }
+ // NOOP, It's Aaaaaall Good.
}
@Override
Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java Fri Jan 10 16:59:22 2014
@@ -22,6 +22,7 @@ import org.apache.solr.client.solrj.bean
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.common.params.CursorMarkParams;
import java.util.*;
@@ -43,6 +44,7 @@ public class QueryResponse extends SolrR
private NamedList<NamedList<Object>> _spellInfo = null;
private NamedList<Object> _statsInfo = null;
private NamedList<NamedList<Number>> _termsInfo = null;
+ private String _cursorMarkNext = null;
// Grouping response
private NamedList<Object> _groupedInfo = null;
@@ -133,6 +135,9 @@ public class QueryResponse extends SolrR
_termsInfo = (NamedList<NamedList<Number>>) res.getVal( i );
extractTermsInfo( _termsInfo );
}
+ else if ( CursorMarkParams.CURSOR_MARK_NEXT.equals( n ) ) {
+ _cursorMarkNext = (String) res.getVal( i );
+ }
}
if(_facetInfo != null) extractFacetInfo( _facetInfo );
}
@@ -487,6 +492,10 @@ public class QueryResponse extends SolrR
public Map<String, FieldStatsInfo> getFieldStatsInfo() {
return _fieldStatsInfo;
}
+
+ public String getNextCursorMark() {
+ return _cursorMarkNext;
+ }
}
Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CommonParams.java Fri Jan 10 16:59:22 2014
@@ -76,15 +76,7 @@ public interface CommonParams {
/** "ping" value for SolrPing action */
public static final String PING = "ping";
// SOLR-4228 end
-
- //Issue 1726 start
- /** score of the last document of the previous page */
- public static final String PAGESCORE ="pageScore";
-
- /** docid of the last document of the previous page */
- public static final String PAGEDOC ="pageDoc";
- //Issue 1726 end
-
+
/** stylesheet to apply to XML results */
public static final String XSL ="xsl";
Modified: lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java (original)
+++ lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java Fri Jan 10 16:59:22 2014
@@ -522,6 +522,14 @@ public abstract class BaseDistributedSea
}
/**
+ * Sets distributed params.
+ * Returns the QueryResponse from {@link #queryServer},
+ */
+ protected QueryResponse query(SolrParams params) throws Exception {
+ return query(true, params);
+ }
+
+ /**
* Returns the QueryResponse from {@link #queryServer}
*/
protected QueryResponse query(boolean setDistribParams, Object[] q) throws Exception {
@@ -531,6 +539,16 @@ public abstract class BaseDistributedSea
for (int i = 0; i < q.length; i += 2) {
params.add(q[i].toString(), q[i + 1].toString());
}
+ return query(setDistribParams, params);
+ }
+
+ /**
+ * Returns the QueryResponse from {@link #queryServer}
+ */
+ protected QueryResponse query(boolean setDistribParams, SolrParams p) throws Exception {
+
+ final ModifiableSolrParams params = new ModifiableSolrParams(p);
+
// TODO: look into why passing true causes fails
params.set("distrib", "false");
final QueryResponse controlRsp = controlClient.query(params);
Modified: lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java?rev=1557196&r1=1557195&r2=1557196&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java (original)
+++ lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java Fri Jan 10 16:59:22 2014
@@ -673,9 +673,10 @@ public abstract class SolrTestCaseJ4 ext
* Validates a query matches some JSON test expressions using the default double delta tolerance.
* @see JSONTestUtil#DEFAULT_DELTA
* @see #assertJQ(SolrQueryRequest,double,String...)
+ * @return The request response as a JSON String if all test patterns pass
*/
- public static void assertJQ(SolrQueryRequest req, String... tests) throws Exception {
- assertJQ(req, JSONTestUtil.DEFAULT_DELTA, tests);
+ public static String assertJQ(SolrQueryRequest req, String... tests) throws Exception {
+ return assertJQ(req, JSONTestUtil.DEFAULT_DELTA, tests);
}
/**
* Validates a query matches some JSON test expressions and closes the
@@ -690,8 +691,9 @@ public abstract class SolrTestCaseJ4 ext
* @param req Solr request to execute
* @param delta tolerance allowed in comparing float/double values
* @param tests JSON path expression + '==' + expected value
+ * @return The request response as a JSON String if all test patterns pass
*/
- public static void assertJQ(SolrQueryRequest req, double delta, String... tests) throws Exception {
+ public static String assertJQ(SolrQueryRequest req, double delta, String... tests) throws Exception {
SolrParams params = null;
try {
params = req.getParams();
@@ -739,6 +741,7 @@ public abstract class SolrTestCaseJ4 ext
}
}
}
+ return response;
} finally {
// restore the params
if (params != null && params != req.getParams()) req.setParams(params);