下面列出了org.apache.lucene.search.spell.SuggestMode#org.apache.solr.common.params.ShardParams 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/** Dispatch shard request in <code>STAGE_EXECUTE_QUERY</code> stage */
@Override
public int distributedProcess(ResponseBuilder rb) {
SolrParams params = rb.req.getParams();
LOG.debug("SuggestComponent distributedProcess with : " + params);
if (rb.stage < ResponseBuilder.STAGE_EXECUTE_QUERY)
return ResponseBuilder.STAGE_EXECUTE_QUERY;
if (rb.stage == ResponseBuilder.STAGE_EXECUTE_QUERY) {
ShardRequest sreq = new ShardRequest();
sreq.purpose = ShardRequest.PURPOSE_GET_TOP_IDS;
sreq.params = new ModifiableSolrParams(rb.req.getParams());
sreq.params.remove(ShardParams.SHARDS);
rb.addRequest(this, sreq);
return ResponseBuilder.STAGE_GET_FIELDS;
}
return ResponseBuilder.STAGE_DONE;
}
private ShardHandler getAndPrepShardHandler(SolrQueryRequest req,
ResponseBuilder rb) {
ShardHandler shardHandler = null;
rb.isDistrib = req.getParams().getBool(
"distrib",
req.getCore().getCoreContainer().isZooKeeperAware());
if (!rb.isDistrib) {
// for back compat, a shards param with URLs like
// localhost:8983/solr will mean that this
// search is distributed.
final String shards = req.getParams().get(ShardParams.SHARDS);
rb.isDistrib = ((shards != null) && (shards.indexOf('/') > 0));
}
if (rb.isDistrib) {
shardHandler = shardHandlerFactory.getShardHandler();
shardHandler.prepDistributed(rb);
if (!rb.isDistrib) {
shardHandler = null; // request is not distributed after all and
// so the shard handler is not needed
}
}
return shardHandler;
}
@Test
@ShardsFixed(num = 2)
public void test() throws Exception {
handle.clear();
handle.put("QTime", SKIPVAL);
handle.put("timestamp", SKIPVAL);
handle.put("maxScore", SKIPVAL);
handle.put("responseHeader", SKIP);
handle.put("spellchecked_response", UNORDERED);
query(CommonParams.QT, "standardResWithCommonMisspellings",
ShardParams.SHARDS_QT, "standardResWithCommonMisspellings",
CommonParams.Q, "foo:bobo AND foo:marley",
SpellingParams.SPELLCHECK_COLLATE, "true",
SpellingParams.SPELLCHECK_BUILD, "true",
SpellingParams.SPELLCHECK_COUNT, "10",
SpellingParams.SPELLCHECK_EXTENDED_RESULTS, "true",
DymReSearcher.COMPONENT_NAME, "true",
SpellCheckComponent.COMPONENT_NAME, "true");
}
/** Check that if the mincount is set as 0 then it is updated to be 1. */
@Test
public void rewriteMincountFacetFieldOption_mincountSetZero_shouldSetMincountToOne()
{
ModifiableSolrParams fixed = new ModifiableSolrParams();
// The user has tried to set the mincount to zero.
when(mockParams.getParameterNamesIterator()).thenReturn(asList("facet.mincount").iterator());
when(mockParams.get("facet.mincount")).thenReturn("0");
when(mockParams.get(ShardParams.SHARDS_PURPOSE)).thenReturn(null);
Map<String, String> fieldMappings = new HashMap<>();
// Call the method under test.
rewriteFacetParametersComponent.rewriteMincountFacetFieldOption(fixed, mockParams, "facet.mincount", fieldMappings,
mockRequest);
// Check that the mincount is set to 1 and the field name is converted to the format stored by Solr.
String actualCount = fixed.get("facet.mincount");
assertEquals("Expected the mincount to be 1.", "1", actualCount);
}
@Test
public void rewriteShardedRequestParameters_mincountSetZero_shouldKeepMincountToZero()
{
ModifiableSolrParams fixed = new ModifiableSolrParams();
// The user has tried to set the mincount to zero.
when(mockParams.getParameterNamesIterator()).thenReturn(asList("facet.mincount").iterator());
when(mockParams.get("facet.mincount")).thenReturn("0");
when(mockParams.get(ShardParams.SHARDS_PURPOSE)).thenReturn(String.valueOf(ShardRequest.PURPOSE_GET_FACETS));
Map<String, String> fieldMappings = new HashMap<>();
// Call the method under test.
rewriteFacetParametersComponent.rewriteMincountFacetFieldOption(fixed, mockParams, "facet.mincount", fieldMappings,
mockRequest);
// Check that the mincount is set to 1 and the field name is converted to the format stored by Solr.
String actualCount = fixed.get("facet.mincount");
assertEquals("Expected no fixed value", null, actualCount);
}
@Test
public void rewriteMincountFacetFieldOption_mincountSetTwo_shouldKeepIt()
{
ModifiableSolrParams fixed = new ModifiableSolrParams();
// The user has tried to set the mincount to zero.
when(mockParams.getParameterNamesIterator()).thenReturn(asList("facet.mincount").iterator());
when(mockParams.get("facet.mincount")).thenReturn("2");
when(mockParams.get(ShardParams.SHARDS_PURPOSE)).thenReturn(null);
Map<String, String> fieldMappings = new HashMap<>();
// Call the method under test.
rewriteFacetParametersComponent.rewriteMincountFacetFieldOption(fixed, mockParams, "facet.mincount", fieldMappings,
mockRequest);
// Check that the mincount is set to 1 and the field name is converted to the format stored by Solr.
String actualCount = fixed.get("facet.mincount");
assertEquals("Expected the mincount to be 2.", "2", actualCount);
}
/** Check that if the mincount is set as 0 then it is updated to be 1. */
@Test
public void rewriteMincountFacetFieldOption_perFieldMincountSetZero_shouldSetPerFieldMincountToOne()
{
ModifiableSolrParams fixed = new ModifiableSolrParams();
// The user has tried to set the mincount to zero.
when(mockParams.getParameterNamesIterator()).thenReturn(asList("f.NAME.facet.mincount","f.CONTENT.facet.mincount").iterator());
when(mockParams.getParams("f.NAME.facet.mincount")).thenReturn(new String[]{"0"});
when(mockParams.getParams("f.CONTENT.facet.mincount")).thenReturn(new String[]{"0"});
when(mockParams.get(ShardParams.SHARDS_PURPOSE)).thenReturn(null);
Map<String, String> fieldMappings = ImmutableMap.of(
"NAME",
"{!afts key=SEARCH.FACET_FIELDS.LOCATION}[email protected][email protected]{http://www.alfresco.org/model/content/1.0}name","CONTENT",
"{!afts key=SEARCH.FACET_FIELDS.LOCATION}[email protected][email protected]{http://www.alfresco.org/model/content/1.0}content");
// Call the method under test.
rewriteFacetParametersComponent.rewriteMincountFacetFieldOption(fixed, mockParams, "facet.mincount", fieldMappings,
mockRequest);
// Check that the mincount is set to 1 and the field name is converted to the format stored by Solr.
String actualNameCount = fixed.get("f.{!afts key=SEARCH.FACET_FIELDS.LOCATION}[email protected][email protected]{http://www.alfresco.org/model/content/1.0}name.facet.mincount");
assertEquals("Expected the mincount to be 1.", "1", actualNameCount);
String actualContentCount = fixed.get("f.{!afts key=SEARCH.FACET_FIELDS.LOCATION}[email protected][email protected]{http://www.alfresco.org/model/content/1.0}content.facet.mincount");
assertEquals("Expected the mincount to be 1.", "1", actualContentCount);
}
@Test
public void rewriteMincountFacetPivotOption_mincountMissing_shouldSetPivotMinCountToOne()
{
// There are no existing facet parameters.
ModifiableSolrParams fixed = new ModifiableSolrParams();
when(mockParams.getParameterNamesIterator()).thenReturn(Iterators.empty());
when(mockParams.get(ShardParams.SHARDS_PURPOSE)).thenReturn(null);
Map<String, String> fieldMappings = new HashMap<>();
// Call the method under test.
rewriteFacetParametersComponent.rewriteMincountFacetFieldOption(fixed, mockParams, "facet.pivot.mincount", fieldMappings,
mockRequest);
// Check that the mincount is set to 1.
String actual = fixed.get("facet.pivot.mincount");
assertEquals("Expected the existing mincount to be preserved.", "1", actual);
}
/** Check that if the mincount is set as 0 then it is updated to be 1. */
@Test
public void rewriteMincountFacetPivotOption_mincountSetZero_shouldSetMincountToOne()
{
ModifiableSolrParams fixed = new ModifiableSolrParams();
// The user has tried to set the mincount to zero.
when(mockParams.getParameterNamesIterator()).thenReturn(asList("facet.pivot.mincount").iterator());
when(mockParams.get("facet.pivot.mincount")).thenReturn("0");
when(mockParams.get(ShardParams.SHARDS_PURPOSE)).thenReturn(null);
Map<String, String> fieldMappings = new HashMap<>();
// Call the method under test.
rewriteFacetParametersComponent.rewriteMincountFacetFieldOption(fixed, mockParams, "facet.pivot.mincount", fieldMappings,
mockRequest);
// Check that the mincount is set to 1 and the field name is converted to the format stored by Solr.
String actualCount = fixed.get("facet.pivot.mincount");
assertEquals("Expected the mincount to be 1.", "1", actualCount);
}
@Test
public void rewriteMincountFacetPivotOption_mincountSetTwo_shouldKeepIt()
{
ModifiableSolrParams fixed = new ModifiableSolrParams();
// The user has tried to set the mincount to zero.
when(mockParams.getParameterNamesIterator()).thenReturn(asList("facet.pivot.mincount").iterator());
when(mockParams.get("facet.pivot.mincount")).thenReturn("2");
when(mockParams.get(ShardParams.SHARDS_PURPOSE)).thenReturn(null);
Map<String, String> fieldMappings = new HashMap<>();
// Call the method under test.
rewriteFacetParametersComponent.rewriteMincountFacetFieldOption(fixed, mockParams, "facet.pivot.mincount", fieldMappings,
mockRequest);
// Check that the mincount is set to 1 and the field name is converted to the format stored by Solr.
String actualCount = fixed.get("facet.pivot.mincount");
assertEquals("Expected the mincount to be 2.", "2", actualCount);
}
private boolean hasCoreUrlPrefix(Object o, String prefix) {
final String s;
if (o instanceof String) {
s = (String)o;
}
else if (o instanceof Replica) {
s = ((Replica)o).getCoreUrl();
} else {
return false;
}
if (prefix.equals(ShardParams.REPLICA_LOCAL)) {
return !StringUtils.isEmpty(localHostAddress) && s.startsWith(localHostAddress);
} else {
return s.startsWith(prefix);
}
}
@Override
public ReplicaListTransformer getInstance(String configSpec, SolrParams requestParams, ReplicaListTransformerFactory fallback) {
ReplicaListTransformer rlt;
if (configSpec == null) {
rlt = AffinityReplicaListTransformer.getInstance(defaultDividendParam, defaultHashParam, requestParams);
} else {
String[] parts = configSpec.split(":", 2);
switch (parts[0]) {
case ShardParams.ROUTING_DIVIDEND:
rlt = AffinityReplicaListTransformer.getInstance(parts.length == 1 ? defaultDividendParam : parts[1], defaultHashParam, requestParams);
break;
case ShardParams.ROUTING_HASH:
rlt = AffinityReplicaListTransformer.getInstance(null, parts.length == 1 ? defaultHashParam : parts[1], requestParams);
break;
default:
throw new IllegalArgumentException("Invalid routing spec: \"" + configSpec + '"');
}
}
return rlt != null ? rlt : fallback.getInstance(null, requestParams, null);
}
public void replicaTypeTest() {
List<Replica> replicas = getBasicReplicaList();
List<PreferenceRule> rules = PreferenceRule.from(ShardParams.SHARDS_PREFERENCE_REPLICA_TYPE + ":NRT," +
ShardParams.SHARDS_PREFERENCE_REPLICA_TYPE + ":TLOG");
NodePreferenceRulesComparator comparator = new NodePreferenceRulesComparator(rules, null);
replicas.sort(comparator);
assertEquals("node1", replicas.get(0).getNodeName());
assertEquals("node2", replicas.get(1).getNodeName());
// reversed rule
rules = PreferenceRule.from(ShardParams.SHARDS_PREFERENCE_REPLICA_TYPE + ":TLOG," +
ShardParams.SHARDS_PREFERENCE_REPLICA_TYPE + ":NRT");
comparator = new NodePreferenceRulesComparator(rules, null);
replicas.sort(comparator);
assertEquals("node2", replicas.get(0).getNodeName());
assertEquals("node1", replicas.get(1).getNodeName());
}
@Test
@ShardsFixed(num = 4)
public void test() throws Exception {
waitForRecoveriesToFinish(false);
assertEquals(4, cloudClient.getZkStateReader().getClusterState().getCollection(DEFAULT_COLLECTION).getSlices().size());
index("id", "a!doc1"); // shard3
index("id", "b!doc1"); // shard1
index("id", "c!doc1"); // shard2
index("id", "e!doc1"); // shard4
commit();
doQuery("a!doc1", "q", "*:*", ShardParams._ROUTE_, "a!"); // can go to any random node
// query shard3 directly with _route_=a! so that we trigger the short circuited request path
Replica shard3 = cloudClient.getZkStateReader().getClusterState().getCollection(DEFAULT_COLLECTION).getLeader("shard3");
String nodeName = shard3.getNodeName();
SolrClient shard3Client = getClient(nodeName);
QueryResponse response = shard3Client.query(new SolrQuery("*:*").add(ShardParams._ROUTE_, "a!").add(ShardParams.SHARDS_INFO, "true"));
assertEquals("Could not find doc", 1, response.getResults().getNumFound());
NamedList<?> sinfo = (NamedList<?>) response.getResponse().get(ShardParams.SHARDS_INFO);
assertNotNull("missing shard info for short circuited request", sinfo);
}
@Override
public void prepare(ResponseBuilder rb) throws IOException {
final SolrParams params = rb.req.getParams();
if (!params.getBool(COMPONENT_NAME, false)) {
return;
}
if (params.getBool(ShardParams.IS_SHARD, false)) {
// only one stage/purpose where we should do any work on a shard
if (0 == (SHARD_PURPOSE & params.getInt(ShardParams.SHARDS_PURPOSE, 0))) {
return;
}
}
// if we're still here, then we should parse & validate our input,
// putting it in the request context so our process method knows it should do work
rb.req.getContext().put(this.getClass(), PhrasesContextData.parseAndValidateRequest(rb.req));
}
@Override
public void process(ResponseBuilder rb) throws IOException {
final PhrasesContextData contextData = (PhrasesContextData) rb.req.getContext().get(this.getClass());
if (null == contextData) {
// if prepare didn't give us anything to work with, then we should do nothing
return;
}
// regardless of single node / shard, we need local stats...
Phrase.populateStats(contextData.allPhrases, contextData.fieldWeights.keySet(), rb.req.getSearcher());
if ( rb.req.getParams().getBool(ShardParams.IS_SHARD, false) ) {
// shard request, return stats for all phrases (in original order)
SimpleOrderedMap<Object> output = new SimpleOrderedMap<>();
output.add("_all", Phrase.formatShardResponse(contextData.allPhrases));
// TODO: might want to add numDocs() & getSumTotalTermFreq(f)/getDocCount(f) stats from each field...
// so that we can sum/merge them for use in scoring?
rb.rsp.add("phrases", output);
} else {
// full single node request...
scoreAndAddResultsToResponse(rb, contextData);
}
}
/** Dispatch shard request in <code>STAGE_EXECUTE_QUERY</code> stage */
@Override
public int distributedProcess(ResponseBuilder rb) {
SolrParams params = rb.req.getParams();
log.info("SuggestComponent distributedProcess with : {}", params);
if (rb.stage < ResponseBuilder.STAGE_EXECUTE_QUERY)
return ResponseBuilder.STAGE_EXECUTE_QUERY;
if (rb.stage == ResponseBuilder.STAGE_EXECUTE_QUERY) {
ShardRequest sreq = new ShardRequest();
sreq.purpose = ShardRequest.PURPOSE_GET_TOP_IDS;
sreq.params = new ModifiableSolrParams(rb.req.getParams());
sreq.params.remove(ShardParams.SHARDS);
rb.addRequest(this, sreq);
return ResponseBuilder.STAGE_GET_FIELDS;
}
return ResponseBuilder.STAGE_DONE;
}
private boolean canShortCircuit(String[] slices, boolean onlyNrtReplicas, SolrParams params, CloudDescriptor cloudDescriptor) {
// Are we hosting the shard that this request is for, and are we active? If so, then handle it ourselves
// and make it a non-distributed request.
String ourSlice = cloudDescriptor.getShardId();
String ourCollection = cloudDescriptor.getCollectionName();
// Some requests may only be fulfilled by replicas of type Replica.Type.NRT
if (slices.length == 1 && slices[0] != null
&& (slices[0].equals(ourSlice) || slices[0].equals(ourCollection + "_" + ourSlice)) // handle the <collection>_<slice> format
&& cloudDescriptor.getLastPublished() == Replica.State.ACTIVE
&& (!onlyNrtReplicas || cloudDescriptor.getReplicaType() == Replica.Type.NRT)) {
boolean shortCircuit = params.getBool("shortCircuit", true); // currently just a debugging parameter to check distrib search on a single node
String targetHandler = params.get(ShardParams.SHARDS_QT);
shortCircuit = shortCircuit && targetHandler == null; // if a different handler is specified, don't short-circuit
return shortCircuit;
}
return false;
}
@Override
public void prepare(ResponseBuilder rb) throws IOException {
SolrParams params = rb.req.getParams();
//the terms parameter is also used by json facet API. So we will get errors if we try to parse as boolean
if (params.get(TermsParams.TERMS, "false").equals("true")) {
rb.doTerms = true;
} else {
return;
}
// TODO: temporary... this should go in a different component.
String shards = params.get(ShardParams.SHARDS);
if (shards != null) {
rb.isDistrib = true;
if (params.get(ShardParams.SHARDS_QT) == null) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No shards.qt parameter specified");
}
List<String> lst = StrUtils.splitSmart(shards, ",", true);
checkShardsWhitelist(rb, lst);
rb.shards = lst.toArray(new String[lst.size()]);
}
}
protected void checkShardsWhitelist(final ResponseBuilder rb, final List<String> lst) {
final List<String> urls = new LinkedList<String>();
for (final String ele : lst) {
urls.addAll(StrUtils.splitSmart(ele, '|'));
}
if (whitelistHostChecker.isWhitelistHostCheckingEnabled() && rb.req.getCore().getCoreContainer().getZkController() == null && !whitelistHostChecker.hasExplicitWhitelist()) {
throw new SolrException(ErrorCode.FORBIDDEN, "TermsComponent "+HttpShardHandlerFactory.INIT_SHARDS_WHITELIST
+" not configured but required when using the '"+ShardParams.SHARDS+"' parameter with the TermsComponent."
+HttpShardHandlerFactory.SET_SOLR_DISABLE_SHARDS_WHITELIST_CLUE);
} else {
ClusterState cs = null;
if (rb.req.getCore().getCoreContainer().getZkController() != null) {
cs = rb.req.getCore().getCoreContainer().getZkController().getClusterState();
}
whitelistHostChecker.checkWhitelist(cs, urls.toString(), urls);
}
}
/**
* Helper method for creating a new ShardRequest for the specified ids, based on the params
* specified for the current request. The new ShardRequest does not yet know anything about
* which shard/slice it will be sent to.
*/
private ShardRequest createShardRequest(final ResponseBuilder rb, final List<String> ids) {
final ShardRequest sreq = new ShardRequest();
sreq.purpose = 1;
sreq.params = new ModifiableSolrParams(rb.req.getParams());
// TODO: how to avoid hardcoding this and hit the same handler?
sreq.params.set(ShardParams.SHARDS_QT,"/get");
sreq.params.set(DISTRIB,false);
sreq.params.remove(ShardParams.SHARDS);
sreq.params.remove(ID);
sreq.params.remove("ids");
sreq.params.set("ids", StrUtils.join(ids, ','));
return sreq;
}
public void testTolerantSearch() throws SolrServerException, IOException {
String badShard = DEAD_HOST_1;
SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.set("debug", "true");
query.set("distrib", "true");
query.setFields("id", "text");
query.set("shards", shard1 + "," + shard2 + "," + badShard);
// verify that the request would fail if shards.tolerant=false
ignoreException("Server refused connection");
expectThrows(SolrException.class, () -> collection1.query(query));
query.set(ShardParams.SHARDS_TOLERANT, "true");
QueryResponse response = collection1.query(query);
assertTrue((Boolean)response.getResponseHeader().get(SolrQueryResponse.RESPONSE_HEADER_PARTIAL_RESULTS_KEY));
@SuppressWarnings("unchecked")
NamedList<String> badShardTrack =
(((NamedList<NamedList<NamedList<String>>>)response.getDebugMap().get("track")).get("EXECUTE_QUERY")).get(badShard);
assertEquals("Unexpected response size for shard", 1, badShardTrack.size());
Entry<String, String> exception = badShardTrack.iterator().next();
assertEquals("Expected key 'Exception' not found", "Exception", exception.getKey());
assertNotNull("Exception message should not be null", exception.getValue());
unIgnoreException("Server refused connection");
}
@Test
public void testWildcardFieldList() throws Exception {
QueryResponse nonDistribRsp = queryWithAsserts("q", "id:19", "fl", "id,*a_sS", "sort", "payload asc");
QueryResponse rsp = queryWithAsserts("q", "id:19", "fl", "id,*a_sS", "sort", "payload asc", "distrib.singlePass", "true");
assertFieldValues(nonDistribRsp.getResults(), "id", "19");
assertFieldValues(rsp.getResults(), "id", "19");
nonDistribRsp = queryWithAsserts("q", "id:19", "fl", "id,dynamic_s,cat*", "sort", "payload asc");
rsp = queryWithAsserts("q", "id:19", "fl", "id,dynamic_s,cat*", "sort", "payload asc", "distrib.singlePass", "true");
assertFieldValues(nonDistribRsp.getResults(), "id", "19");
assertFieldValues(rsp.getResults(), "id", "19");
queryWithAsserts("q", "id:19", "fl", "id,*a_sS", "sort", "payload asc", "distrib.singlePass", "true");
queryWithAsserts("q", "id:19", "fl", "id,dynamic_s,cat*", "sort", "payload asc", "distrib.singlePass", "true");
// fl=*
queryWithAsserts("q", "*:*", "fl", "*", "sort", "payload desc", ShardParams.DISTRIB_SINGLE_PASS, "true");
queryWithAsserts("q", "*:*", "fl", "*", "sort", "payload desc");
// fl=*,score
queryWithAsserts("q", "*:*", "fl", "*,score", "sort", "payload desc", ShardParams.DISTRIB_SINGLE_PASS, "true");
queryWithAsserts("q", "*:*", "fl", "*,score", "sort", "payload desc");
}
@Override
public void process(ResponseBuilder rb) throws IOException
{
SolrQueryRequest req = rb.req;
AlfrescoCoreAdminHandler adminHandler = (AlfrescoCoreAdminHandler)
req.getCore().
getCoreContainer().
getMultiCoreHandler();
boolean isShard = rb.req.getParams().getBool(ShardParams.IS_SHARD, false);
MetadataTracker metaTrkr = adminHandler.getTrackerRegistry().getTrackerForCore(req.getCore().getName(), MetadataTracker.class);
if(metaTrkr != null && !isShard)
{
TrackerState metadataTrkrState = metaTrkr.getTrackerState();
long lastIndexedTx = metadataTrkrState.getLastIndexedTxId();
long lastIndexTxCommitTime = metadataTrkrState.getLastIndexedTxCommitTime();
long lastTxIdOnServer = metadataTrkrState.getLastTxIdOnServer();
long transactionsToDo = lastTxIdOnServer - lastIndexedTx;
if (transactionsToDo < 0)
{
transactionsToDo = 0;
}
rb.rsp.add("lastIndexedTx", lastIndexedTx);
rb.rsp.add("lastIndexedTxTime", lastIndexTxCommitTime);
rb.rsp.add("txRemaining", transactionsToDo);
}
}
@Test
public void rewriteMincountFacetFieldOption_perFieldMincountSetZero_shouldSetPerFieldMincountAndMincountToOne()
{
ModifiableSolrParams fixed = new ModifiableSolrParams();
// The user has tried to set the mincount to zero.
when(mockParams.getParameterNamesIterator()).thenReturn(asList("f.NAME.facet.mincount","f.CONTENT.facet.mincount").iterator());
when(mockParams.getParams("f.NAME.facet.mincount")).thenReturn(new String[]{"0"});
when(mockParams.getParams("f.CONTENT.facet.mincount")).thenReturn(new String[]{"0"});
when(mockParams.get(ShardParams.SHARDS_PURPOSE)).thenReturn(null);
Map<String, String> fieldMappings = ImmutableMap.of(
"NAME",
"{!afts key=SEARCH.FACET_FIELDS.LOCATION}[email protected][email protected]{http://www.alfresco.org/model/content/1.0}name","CONTENT",
"{!afts key=SEARCH.FACET_FIELDS.LOCATION}[email protected][email protected]{http://www.alfresco.org/model/content/1.0}content");
// Call the method under test.
rewriteFacetParametersComponent.rewriteMincountFacetFieldOption(fixed, mockParams, "facet.mincount", fieldMappings,
mockRequest);
// Check that the mincount is set to 1 and the field name is converted to the format stored by Solr.
String actualNameCount = fixed.get("f.{!afts key=SEARCH.FACET_FIELDS.LOCATION}[email protected][email protected]{http://www.alfresco.org/model/content/1.0}name.facet.mincount");
assertEquals("Expected the mincount to be 1.", "1", actualNameCount);
String actualContentCount = fixed.get("f.{!afts key=SEARCH.FACET_FIELDS.LOCATION}[email protected][email protected]{http://www.alfresco.org/model/content/1.0}content.facet.mincount");
assertEquals("Expected the mincount to be 1.", "1", actualContentCount);
String actualCount = fixed.get("facet.mincount");
assertEquals("Expected the mincount to be 1.", "1", actualCount);
}
@Override
public SolrParams getParams() {
ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
if (collection != null) {
params.set(CoreAdminParams.COLLECTION, collection);
}
if (shardName != null) {
params.set(CoreAdminParams.SHARD, shardName);
}
if (routeKey != null) {
params.set(ShardParams._ROUTE_, routeKey);
}
return params;
}
public NodePreferenceRulesComparator(final List<PreferenceRule> preferenceRules, final SolrParams requestParams,
final String nodeName, final String localHostAddress, final NodesSysPropsCacher sysPropsCache,
final ReplicaListTransformerFactory defaultRltFactory, final ReplicaListTransformerFactory stableRltFactory) {
this.sysPropsCache = sysPropsCache;
this.preferenceRules = preferenceRules;
this.nodeName = nodeName;
this.localHostAddress = localHostAddress;
final int maxIdx = preferenceRules.size() - 1;
final PreferenceRule lastRule = preferenceRules.get(maxIdx);
if (!ShardParams.SHARDS_PREFERENCE_REPLICA_BASE.equals(lastRule.name)) {
this.sortRules = preferenceRules;
this.baseReplicaListTransformer = defaultRltFactory.getInstance(null, requestParams, RequestReplicaListTransformerGenerator.RANDOM_RLTF);
} else {
if (maxIdx == 0) {
this.sortRules = null;
} else {
this.sortRules = preferenceRules.subList(0, maxIdx);
}
String[] parts = lastRule.value.split(":", 2);
switch (parts[0]) {
case ShardParams.REPLICA_RANDOM:
this.baseReplicaListTransformer = RequestReplicaListTransformerGenerator.RANDOM_RLTF.getInstance(parts.length == 1 ? null : parts[1], requestParams, null);
break;
case ShardParams.REPLICA_STABLE:
this.baseReplicaListTransformer = stableRltFactory.getInstance(parts.length == 1 ? null : parts[1], requestParams, RequestReplicaListTransformerGenerator.RANDOM_RLTF);
break;
default:
throw new IllegalArgumentException("Invalid base replica order spec");
}
}
}
@Override
public int compare(Object left, Object right) {
if (this.sortRules != null) {
for (PreferenceRule preferenceRule: this.sortRules) {
final boolean lhs;
final boolean rhs;
switch (preferenceRule.name) {
case ShardParams.SHARDS_PREFERENCE_REPLICA_TYPE:
lhs = hasReplicaType(left, preferenceRule.value);
rhs = hasReplicaType(right, preferenceRule.value);
break;
case ShardParams.SHARDS_PREFERENCE_REPLICA_LOCATION:
lhs = hasCoreUrlPrefix(left, preferenceRule.value);
rhs = hasCoreUrlPrefix(right, preferenceRule.value);
break;
case ShardParams.SHARDS_PREFERENCE_NODE_WITH_SAME_SYSPROP:
if (sysPropsCache == null) {
throw new IllegalArgumentException("Unable to get the NodesSysPropsCacher on sorting replicas by preference:"+ preferenceRule.value);
}
lhs = hasSameMetric(left, preferenceRule.value);
rhs = hasSameMetric(right, preferenceRule.value);
break;
case ShardParams.SHARDS_PREFERENCE_REPLICA_BASE:
throw new IllegalArgumentException("only one base replica order may be specified in "
+ ShardParams.SHARDS_PREFERENCE + ", and it must be specified last");
default:
throw new IllegalArgumentException("Invalid " + ShardParams.SHARDS_PREFERENCE + " type: " + preferenceRule.name);
}
if (lhs != rhs) {
return lhs ? -1 : +1;
}
}
}
return 0;
}
public static List<PreferenceRule> from(String rules) {
List<String> prefs = StrUtils.splitSmart(rules, ',');
ArrayList<PreferenceRule> preferenceRules = new ArrayList<>(prefs.size());
prefs.forEach(rule -> {
String[] parts = rule.split(":", 2);
if (parts.length != 2) {
throw new IllegalArgumentException("Invalid " + ShardParams.SHARDS_PREFERENCE + " rule: " + rule);
}
preferenceRules.add(new PreferenceRule(parts[0], parts[1]));
});
return preferenceRules;
}
public ReplicaListTransformer getReplicaListTransformer(final SolrParams requestParams, String defaultShardPreferences, String nodeName, String localHostAddress, NodesSysPropsCacher sysPropsCacher) {
@SuppressWarnings("deprecation")
final boolean preferLocalShards = requestParams.getBool(CommonParams.PREFER_LOCAL_SHARDS, false);
defaultShardPreferences = Optional.ofNullable(defaultShardPreferences).orElse(this.defaultShardPreferences);
final String shardsPreferenceSpec = requestParams.get(ShardParams.SHARDS_PREFERENCE, defaultShardPreferences);
if (preferLocalShards || !shardsPreferenceSpec.isEmpty()) {
if (preferLocalShards && !shardsPreferenceSpec.isEmpty()) {
throw new SolrException(
ErrorCode.BAD_REQUEST,
"preferLocalShards is deprecated and must not be used with shards.preference"
);
}
List<PreferenceRule> preferenceRules = PreferenceRule.from(shardsPreferenceSpec);
if (preferLocalShards) {
preferenceRules.add(new PreferenceRule(ShardParams.SHARDS_PREFERENCE_REPLICA_LOCATION, ShardParams.REPLICA_LOCAL));
}
NodePreferenceRulesComparator replicaComp =
new NodePreferenceRulesComparator(
preferenceRules,
requestParams,
Optional.ofNullable(nodeName).orElse(this.nodeName),
Optional.ofNullable(localHostAddress).orElse(this.localHostAddress),
Optional.ofNullable(sysPropsCacher).orElse(this.sysPropsCacher),
defaultRltFactory,
stableRltFactory);
ReplicaListTransformer baseReplicaListTransformer = replicaComp.getBaseReplicaListTransformer();
if (replicaComp.getSortRules() == null) {
// only applying base transformation
return baseReplicaListTransformer;
} else {
return new TopLevelReplicaListTransformer(replicaComp, baseReplicaListTransformer);
}
}
return defaultRltFactory.getInstance(null, requestParams, RANDOM_RLTF);
}