/** * get the solr document list from a query response This differs from getResponseByParams in such * a way that it does only create the fields of the response but never search snippets and there * are also no facets generated. * * @param params * @return * @throws IOException * @throws SolrException */ @Override public SolrDocumentList getDocumentListByParams(ModifiableSolrParams params) throws IOException, SolrException { SolrQueryRequest req = this.request(params); SolrQueryResponse response = null; String q = params.get(CommonParams.Q); String fq = params.get(CommonParams.FQ); String sort = params.get(CommonParams.SORT); String threadname = Thread.currentThread().getName(); try { if (q != null) Thread.currentThread() .setName( "solr query: q = " + q + (fq == null ? "" : ", fq = " + fq) + (sort == null ? "" : ", sort = " + sort)); // for debugging in Threaddump response = this.query(req); if (q != null) Thread.currentThread().setName(threadname); if (response == null) throw new IOException("response == null"); return SolrQueryResponse2SolrDocumentList(req, response); } finally { req.close(); SolrRequestInfo.clearRequestInfo(); } }
/** * Adds extra parameters to a Solr query for better term searches, including custom options. More * specifically, adds parameters for requesting the score to be included in the results, for * requesting a spellcheck result, and sets the {@code start} and {@code rows} parameters when * missing. * * @param originalParams the original Solr parameters to enhance * @param queryOptions extra options to include in the query; these override the default values, * but don't override values already set in the query * @return the enhanced parameters */ public static SolrParams enhanceParams( SolrParams originalParams, Map<String, String> queryOptions) { if (originalParams == null) { return null; } ModifiableSolrParams newParams = new ModifiableSolrParams(); newParams.set(CommonParams.START, "0"); newParams.set(CommonParams.ROWS, "1000"); newParams.set(CommonParams.FL, "* score"); if (queryOptions != null) { for (Map.Entry<String, String> item : queryOptions.entrySet()) { newParams.set(item.getKey(), item.getValue()); } } for (Map.Entry<String, Object> item : originalParams.toNamedList()) { if (item.getValue() != null && item.getValue() instanceof String[]) { newParams.set(item.getKey(), (String[]) item.getValue()); } else { newParams.set(item.getKey(), String.valueOf(item.getValue())); } } if (newParams.get(SPELLCHECK) == null) { newParams.set(SPELLCHECK, Boolean.toString(true)); newParams.set(SpellingParams.SPELLCHECK_COLLATE, Boolean.toString(true)); } return newParams; }
/** * Replaces the original query in the Solr parameters with the suggested spellchecked query. It * also fixes the boost query, if any. * * @param originalParams the original Solr parameters to fix * @param suggestedQuery the suggested query * @return new Solr parameters with the query and boost query fixed */ public static SolrParams applySpellcheckSuggestion( SolrParams originalParams, String suggestedQuery) { if (originalParams == null) { return null; } if (StringUtils.isBlank(suggestedQuery)) { return originalParams; } ModifiableSolrParams newParams = new ModifiableSolrParams(originalParams); String newQuery = suggestedQuery; // Since the spelling suggestion might not be that good, also search for the original user input if (StringUtils.isNotEmpty(originalParams.get(SpellingParams.SPELLCHECK_Q))) { newQuery = originalParams.get(CommonParams.Q) + "^10 " + suggestedQuery; } // Check if the last term in the query is a word stub search which, in case the request comes // from a // user-triggered search for terms from the UI, is a prefix search for the last typed word Matcher originalStub = WORD_STUB.matcher(newParams.get(CommonParams.Q)); Matcher newStub = WORD_STUB.matcher(suggestedQuery); if (originalStub.find() && newStub.find() && !StringUtils.equals(originalStub.group(2), newStub.group(2))) { // Since word stubs aren't complete words, they may wrongly be "corrected" to a full word that // doesn't match // what the user started typing; include both the original stub and the "corrected" stub in // the query newQuery += ' ' + originalStub.group() + "^1.5"; // Also fix the boost query String boostQuery = newParams.get(DisMaxParams.BQ); if (StringUtils.isNotEmpty(boostQuery)) { newParams.add(DisMaxParams.BQ, boostQuery.replace(originalStub.group(2), newStub.group(2))); } } // Replace the query newParams.set(CommonParams.Q, newQuery); return newParams; }
private NamedList<Object> directUpdate(AbstractUpdateRequest request, ClusterState clusterState) throws SolrServerException { UpdateRequest updateRequest = (UpdateRequest) request; ModifiableSolrParams params = (ModifiableSolrParams) request.getParams(); ModifiableSolrParams routableParams = new ModifiableSolrParams(); ModifiableSolrParams nonRoutableParams = new ModifiableSolrParams(); if (params != null) { nonRoutableParams.add(params); routableParams.add(params); for (String param : NON_ROUTABLE_PARAMS) { routableParams.remove(param); } } String collection = nonRoutableParams.get(UpdateParams.COLLECTION, defaultCollection); if (collection == null) { throw new SolrServerException( "No collection param specified on request and no default collection has been set."); } // Check to see if the collection is an alias. Aliases aliases = zkStateReader.getAliases(); if (aliases != null) { Map<String, String> collectionAliases = aliases.getCollectionAliasMap(); if (collectionAliases != null && collectionAliases.containsKey(collection)) { collection = collectionAliases.get(collection); } } DocCollection col = getDocCollection(clusterState, collection); DocRouter router = col.getRouter(); if (router instanceof ImplicitDocRouter) { // short circuit as optimization return null; } // Create the URL map, which is keyed on slice name. // The value is a list of URLs for each replica in the slice. // The first value in the list is the leader for the slice. Map<String, List<String>> urlMap = buildUrlMap(col); if (urlMap == null) { // we could not find a leader yet - use unoptimized general path return null; } NamedList<Throwable> exceptions = new NamedList<>(); NamedList<NamedList> shardResponses = new NamedList<>(); Map<String, LBHttpSolrServer.Req> routes = updateRequest.getRoutes(router, col, urlMap, routableParams, this.idField); if (routes == null) { return null; } long start = System.nanoTime(); if (parallelUpdates) { final Map<String, Future<NamedList<?>>> responseFutures = new HashMap<>(routes.size()); for (final Map.Entry<String, LBHttpSolrServer.Req> entry : routes.entrySet()) { final String url = entry.getKey(); final LBHttpSolrServer.Req lbRequest = entry.getValue(); responseFutures.put( url, threadPool.submit( new Callable<NamedList<?>>() { @Override public NamedList<?> call() throws Exception { return lbServer.request(lbRequest).getResponse(); } })); } for (final Map.Entry<String, Future<NamedList<?>>> entry : responseFutures.entrySet()) { final String url = entry.getKey(); final Future<NamedList<?>> responseFuture = entry.getValue(); try { shardResponses.add(url, responseFuture.get()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } catch (ExecutionException e) { exceptions.add(url, e.getCause()); } } if (exceptions.size() > 0) { throw new RouteException(ErrorCode.SERVER_ERROR, exceptions, routes); } } else { for (Map.Entry<String, LBHttpSolrServer.Req> entry : routes.entrySet()) { String url = entry.getKey(); LBHttpSolrServer.Req lbRequest = entry.getValue(); try { NamedList<Object> rsp = lbServer.request(lbRequest).getResponse(); shardResponses.add(url, rsp); } catch (Exception e) { throw new SolrServerException(e); } } } UpdateRequest nonRoutableRequest = null; List<String> deleteQuery = updateRequest.getDeleteQuery(); if (deleteQuery != null && deleteQuery.size() > 0) { UpdateRequest deleteQueryRequest = new UpdateRequest(); deleteQueryRequest.setDeleteQuery(deleteQuery); nonRoutableRequest = deleteQueryRequest; } Set<String> paramNames = nonRoutableParams.getParameterNames(); Set<String> intersection = new HashSet<>(paramNames); intersection.retainAll(NON_ROUTABLE_PARAMS); if (nonRoutableRequest != null || intersection.size() > 0) { if (nonRoutableRequest == null) { nonRoutableRequest = new UpdateRequest(); } nonRoutableRequest.setParams(nonRoutableParams); List<String> urlList = new ArrayList<>(); urlList.addAll(routes.keySet()); Collections.shuffle(urlList, rand); LBHttpSolrServer.Req req = new LBHttpSolrServer.Req(nonRoutableRequest, urlList); try { LBHttpSolrServer.Rsp rsp = lbServer.request(req); shardResponses.add(urlList.get(0), rsp.getResponse()); } catch (Exception e) { throw new SolrException(ErrorCode.SERVER_ERROR, urlList.get(0), e); } } long end = System.nanoTime(); RouteResponse rr = condenseResponse(shardResponses, (long) ((end - start) / 1000000)); rr.setRouteResponses(shardResponses); rr.setRoutes(routes); return rr; }