mirror of https://github.com/apache/lucene.git
SOLR-3134: Include shard info in distributed response when shards.info=true
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1292717 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6ff799d4b3
commit
d1abb09612
|
@ -1,4 +1,4 @@
|
||||||
Apache Solr Release Notes
|
Apache Solr Release Notes
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
@ -227,6 +227,8 @@ New Features
|
||||||
* SOLR-2459: Expose LogLevel selection with a RequestHandler rather then servlet
|
* SOLR-2459: Expose LogLevel selection with a RequestHandler rather then servlet
|
||||||
(Stefan Matheis, Upayavira, ryan)
|
(Stefan Matheis, Upayavira, ryan)
|
||||||
|
|
||||||
|
* SOLR-3134: Include shard info in distributed response when shards.info=true (ryan)
|
||||||
|
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
@ -39,12 +39,13 @@ import org.apache.solr.common.params.ShardParams;
|
||||||
import org.apache.solr.common.params.SolrParams;
|
import org.apache.solr.common.params.SolrParams;
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.common.util.StrUtils;
|
import org.apache.solr.common.util.StrUtils;
|
||||||
import org.apache.solr.core.CoreDescriptor;
|
import org.apache.solr.core.CoreDescriptor;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
|
|
||||||
import java.util.*;
|
import java.net.ConnectException;
|
||||||
import java.util.concurrent.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class HttpShardHandler extends ShardHandler {
|
public class HttpShardHandler extends ShardHandler {
|
||||||
|
|
||||||
private HttpShardHandlerFactory httpShardHandlerFactory;
|
private HttpShardHandlerFactory httpShardHandlerFactory;
|
||||||
|
@ -155,12 +156,15 @@ public class HttpShardHandler extends ShardHandler {
|
||||||
ssr.nl = server.request(req);
|
ssr.nl = server.request(req);
|
||||||
} else {
|
} else {
|
||||||
LBHttpSolrServer.Rsp rsp = httpShardHandlerFactory.loadbalancer.request(new LBHttpSolrServer.Req(req, urls));
|
LBHttpSolrServer.Rsp rsp = httpShardHandlerFactory.loadbalancer.request(new LBHttpSolrServer.Req(req, urls));
|
||||||
ssr.nl = rsp.getResponse();
|
ssr.nl = rsp.getResponse();
|
||||||
srsp.setShardAddress(rsp.getServer());
|
srsp.setShardAddress(rsp.getServer());
|
||||||
}
|
}
|
||||||
} catch (Throwable th) {
|
}
|
||||||
srsp.setException(th);
|
catch( ConnectException cex ) {
|
||||||
if (th instanceof SolrException) {
|
srsp.setException(cex); //????
|
||||||
|
} catch (Throwable th) {
|
||||||
|
srsp.setException(th);
|
||||||
|
if (th instanceof SolrException) {
|
||||||
srsp.setResponseCode(((SolrException)th).code());
|
srsp.setResponseCode(((SolrException)th).code());
|
||||||
} else {
|
} else {
|
||||||
srsp.setResponseCode(-1);
|
srsp.setResponseCode(-1);
|
||||||
|
@ -245,13 +249,13 @@ public class HttpShardHandler extends ShardHandler {
|
||||||
String shards = params.get(ShardParams.SHARDS);
|
String shards = params.get(ShardParams.SHARDS);
|
||||||
|
|
||||||
// for back compat, a shards param with URLs like localhost:8983/solr will mean that this
|
// for back compat, a shards param with URLs like localhost:8983/solr will mean that this
|
||||||
// search is distributed.
|
// search is distributed.
|
||||||
boolean hasShardURL = shards != null && shards.indexOf('/') > 0;
|
boolean hasShardURL = shards != null && shards.indexOf('/') > 0;
|
||||||
rb.isDistrib = hasShardURL | rb.isDistrib;
|
rb.isDistrib = hasShardURL | rb.isDistrib;
|
||||||
|
|
||||||
if (rb.isDistrib) {
|
if (rb.isDistrib) {
|
||||||
// since the cost of grabbing cloud state is still up in the air, we grab it only
|
// since the cost of grabbing cloud state is still up in the air, we grab it only
|
||||||
// if we need it.
|
// if we need it.
|
||||||
CloudState cloudState = null;
|
CloudState cloudState = null;
|
||||||
Map<String,Slice> slices = null;
|
Map<String,Slice> slices = null;
|
||||||
CoreDescriptor coreDescriptor = req.getCore().getCoreDescriptor();
|
CoreDescriptor coreDescriptor = req.getCore().getCoreDescriptor();
|
||||||
|
|
|
@ -44,6 +44,7 @@ import org.apache.solr.common.cloud.ZkNodeProps;
|
||||||
import org.apache.solr.common.cloud.ZkStateReader;
|
import org.apache.solr.common.cloud.ZkStateReader;
|
||||||
import org.apache.solr.common.params.*;
|
import org.apache.solr.common.params.*;
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.apache.solr.common.util.NamedList;
|
||||||
|
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||||
import org.apache.solr.common.util.StrUtils;
|
import org.apache.solr.common.util.StrUtils;
|
||||||
import org.apache.solr.core.CoreDescriptor;
|
import org.apache.solr.core.CoreDescriptor;
|
||||||
import org.apache.solr.request.SolrQueryRequest;
|
import org.apache.solr.request.SolrQueryRequest;
|
||||||
|
@ -768,11 +769,28 @@ public class QueryComponent extends SearchComponent
|
||||||
ShardFieldSortedHitQueue queue;
|
ShardFieldSortedHitQueue queue;
|
||||||
queue = new ShardFieldSortedHitQueue(sortFields, ss.getOffset() + ss.getCount());
|
queue = new ShardFieldSortedHitQueue(sortFields, ss.getOffset() + ss.getCount());
|
||||||
|
|
||||||
|
NamedList<Object> shardInfo = null;
|
||||||
|
if(rb.req.getParams().getBool(ShardParams.SHARDS_INFO, false)) {
|
||||||
|
shardInfo = (NamedList<Object>) rb.rsp.getValues().get(ShardParams.SHARDS_INFO);
|
||||||
|
if(shardInfo==null) {
|
||||||
|
shardInfo = new SimpleOrderedMap<Object>();
|
||||||
|
rb.rsp.getValues().add(ShardParams.SHARDS_INFO,shardInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long numFound = 0;
|
long numFound = 0;
|
||||||
Float maxScore=null;
|
Float maxScore=null;
|
||||||
for (ShardResponse srsp : sreq.responses) {
|
for (ShardResponse srsp : sreq.responses) {
|
||||||
SolrDocumentList docs = (SolrDocumentList)srsp.getSolrResponse().getResponse().get("response");
|
SolrDocumentList docs = (SolrDocumentList)srsp.getSolrResponse().getResponse().get("response");
|
||||||
|
|
||||||
|
if(shardInfo!=null) {
|
||||||
|
SimpleOrderedMap<Object> nl = new SimpleOrderedMap<Object>();
|
||||||
|
nl.add("numFound", docs.getNumFound());
|
||||||
|
nl.add("maxScore", docs.getMaxScore());
|
||||||
|
nl.add("time", srsp.getSolrResponse().getElapsedTime());
|
||||||
|
shardInfo.add(srsp.getShard(), nl);
|
||||||
|
}
|
||||||
|
|
||||||
// calculate global maxScore and numDocsFound
|
// calculate global maxScore and numDocsFound
|
||||||
if (docs.getMaxScore() != null) {
|
if (docs.getMaxScore() != null) {
|
||||||
maxScore = maxScore==null ? docs.getMaxScore() : Math.max(maxScore, docs.getMaxScore());
|
maxScore = maxScore==null ? docs.getMaxScore() : Math.max(maxScore, docs.getMaxScore());
|
||||||
|
|
|
@ -18,11 +18,14 @@
|
||||||
package org.apache.solr.handler.component;
|
package org.apache.solr.handler.component;
|
||||||
|
|
||||||
import org.apache.lucene.queryparser.classic.ParseException;
|
import org.apache.lucene.queryparser.classic.ParseException;
|
||||||
|
import org.apache.solr.client.solrj.SolrServerException;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.params.CommonParams;
|
import org.apache.solr.common.params.CommonParams;
|
||||||
import org.apache.solr.common.params.ModifiableSolrParams;
|
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||||
import org.apache.solr.common.params.ShardParams;
|
import org.apache.solr.common.params.ShardParams;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.common.util.RTimer;
|
import org.apache.solr.common.util.RTimer;
|
||||||
|
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||||
import org.apache.solr.core.CloseHook;
|
import org.apache.solr.core.CloseHook;
|
||||||
import org.apache.solr.core.PluginInfo;
|
import org.apache.solr.core.PluginInfo;
|
||||||
import org.apache.solr.core.SolrCore;
|
import org.apache.solr.core.SolrCore;
|
||||||
|
@ -35,6 +38,8 @@ import org.apache.solr.util.plugin.SolrCoreAware;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -283,14 +288,40 @@ public class SearchHandler extends RequestHandlerBase implements SolrCoreAware ,
|
||||||
ShardResponse srsp = shardHandler1.takeCompletedOrError();
|
ShardResponse srsp = shardHandler1.takeCompletedOrError();
|
||||||
if (srsp == null) break; // no more requests to wait for
|
if (srsp == null) break; // no more requests to wait for
|
||||||
|
|
||||||
// Was there an exception? If so, abort everything and
|
// Was there an exception?
|
||||||
// rethrow
|
|
||||||
if (srsp.getException() != null) {
|
if (srsp.getException() != null) {
|
||||||
shardHandler1.cancelAll();
|
// If things are tolerant, just continue
|
||||||
if (srsp.getException() instanceof SolrException) {
|
if(rb.req.getParams().getBool(ShardParams.SHARDS_TOLERANT, false)) {
|
||||||
throw (SolrException)srsp.getException();
|
if( rb.req.getParams().getBool(ShardParams.SHARDS_INFO, false) ) {
|
||||||
} else {
|
NamedList<Object> sinfo = (NamedList<Object>) rb.rsp.getValues().get(ShardParams.SHARDS_INFO);
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, srsp.getException());
|
if(sinfo==null) {
|
||||||
|
sinfo = new SimpleOrderedMap<Object>();
|
||||||
|
rb.rsp.getValues().add(ShardParams.SHARDS_INFO,sinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleOrderedMap<Object> nl = new SimpleOrderedMap<Object>();
|
||||||
|
Throwable t = srsp.getException();
|
||||||
|
if(t instanceof SolrServerException) {
|
||||||
|
t = ((SolrServerException)t).getCause();
|
||||||
|
}
|
||||||
|
nl.add("error", t.toString() );
|
||||||
|
|
||||||
|
StringWriter trace = new StringWriter();
|
||||||
|
t.printStackTrace(new PrintWriter(trace));
|
||||||
|
nl.add("trace", trace.toString() );
|
||||||
|
if(srsp.getSolrResponse()!=null){
|
||||||
|
nl.add("time", srsp.getSolrResponse().getElapsedTime());
|
||||||
|
}
|
||||||
|
sinfo.add(srsp.getShard(), nl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // If so, abort everything and rethrow
|
||||||
|
shardHandler1.cancelAll();
|
||||||
|
if (srsp.getException() instanceof SolrException) {
|
||||||
|
throw (SolrException)srsp.getException();
|
||||||
|
} else {
|
||||||
|
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, srsp.getException());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,12 @@
|
||||||
|
|
||||||
package org.apache.solr;
|
package org.apache.solr;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
import org.apache.solr.common.params.CommonParams;
|
import org.apache.solr.common.params.CommonParams;
|
||||||
|
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||||
|
import org.apache.solr.common.params.ShardParams;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO? perhaps use:
|
* TODO? perhaps use:
|
||||||
|
@ -274,6 +279,22 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
|
||||||
query("q", "id:[1 TO 5]", CommonParams.DEBUG, CommonParams.RESULTS);
|
query("q", "id:[1 TO 5]", CommonParams.DEBUG, CommonParams.RESULTS);
|
||||||
query("q", "id:[1 TO 5]", CommonParams.DEBUG, CommonParams.QUERY);
|
query("q", "id:[1 TO 5]", CommonParams.DEBUG, CommonParams.QUERY);
|
||||||
|
|
||||||
|
// Check Info is added to for each shard
|
||||||
|
ModifiableSolrParams q = new ModifiableSolrParams();
|
||||||
|
q.set("q", "*:*");
|
||||||
|
q.set(ShardParams.SHARDS_INFO, true);
|
||||||
|
setDistributedParams(q);
|
||||||
|
QueryResponse rsp = queryServer(q);
|
||||||
|
NamedList<?> sinfo = (NamedList<?>) rsp.getResponse().get(ShardParams.SHARDS_INFO);
|
||||||
|
String shards = getShardsString();
|
||||||
|
int cnt = StringUtils.countMatches(shards, ",")+1;
|
||||||
|
|
||||||
|
assertNotNull("missing shard info", sinfo);
|
||||||
|
assertEquals("should have an entry for each shard ["+sinfo+"] "+shards, cnt, sinfo.size());
|
||||||
|
|
||||||
|
|
||||||
|
// This index has the same number for every field
|
||||||
|
|
||||||
// TODO: This test currently fails because debug info is obtained only
|
// TODO: This test currently fails because debug info is obtained only
|
||||||
// on shards with matches.
|
// on shards with matches.
|
||||||
// query("q","matchesnothing","fl","*,score", "debugQuery", "true");
|
// query("q","matchesnothing","fl","*,score", "debugQuery", "true");
|
||||||
|
|
|
@ -39,4 +39,10 @@ public interface ShardParams {
|
||||||
|
|
||||||
/** query type for shard requests */
|
/** query type for shard requests */
|
||||||
public static final String SHARDS_QT = "shards.qt";
|
public static final String SHARDS_QT = "shards.qt";
|
||||||
|
|
||||||
|
/** Request detailed match info for each shard (true/false) */
|
||||||
|
public static final String SHARDS_INFO = "shards.info";
|
||||||
|
|
||||||
|
/** Should things fail if there is an error? (true/false) */
|
||||||
|
public static final String SHARDS_TOLERANT = "shards.tolerant";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue