private byte[] getSummaryClassAsUtf8() { if (query.getPresentation().getSummary() != null) { return Utf8.toBytes(query.getPresentation().getSummary()); } return new byte[0]; }
if (key.last().equals(Presentation.SUMMARY)) return query.getPresentation().getSummary(); if (key.last().equals(Presentation.FORMAT)) return query.getPresentation().getFormat(); if (key.last().equals(Presentation.TIMING)) return query.getPresentation().getTiming();
/** * Fill hit properties with data using the default summary * class, possibly overridden with the 'summary' request parameter. * <p> * Fill <b>must</b> be called before any property (accessed by * getProperty/getField) is accessed on the hit. It should be done * as late as possible for performance reasons. * <p> * Calling this on already filled results has no cost. * * @param result the result to fill */ public void fill(Result result) { fill(result, result.getQuery().getPresentation().getSummary()); }
protected void storeID(Hit hit, Execution execution) { String id = getProperty(hit, blendingField); if (id != null) { documentsToStrip.add(id); } else { if (!result.isFilled(result.getQuery().getPresentation().getSummary())) { fill(result, result.getQuery().getPresentation().getSummary(), execution); id = getProperty(hit, blendingField); if (id != null) { documentsToStrip.add(id); } } } }
public FutureResult searchAndFill(Query query) { return getFutureResult(() -> { Result result = execution.search(query); execution.fill(result, query.getPresentation().getSummary()); return result; }, query); }
protected boolean known(HitGroup source, Hit hit, Execution execution) { String stripID = getProperty(hit, blendingField); if (stripID == null) { if (!source.isFilled(result.getQuery().getPresentation().getSummary())) { Result nResult = new Result(result.getQuery()); nResult.hits().add(source); fill(nResult, nResult.getQuery().getPresentation().getSummary(), execution); stripID = getProperty(hit, blendingField); if (stripID == null) { return false; } } else { return false; } } if (documentsToStrip.contains(stripID)) { return true; } documentsToStrip.add(stripID); return false; }
/** * Converts the given {@link GroupingRequest} into a set of {@link Grouping} objects. The returned object holds the * context that corresponds to the given request, whereas the created {@link Grouping} objects are written directly * to the given map. * * @param query The query being executed. * @param req The request to convert. * @param map The grouping map to write to. * @return The context required to identify the request results. */ private RequestContext convertRequest(Query query, GroupingRequest req, int requestId, Map<Integer, Grouping> map) { RequestBuilder builder = new RequestBuilder(requestId); builder.setRootOperation(req.getRootOperation()); builder.setDefaultSummaryName(query.getPresentation().getSummary()); builder.setTimeZone(req.getTimeZone()); builder.addContinuations(req.continuations()); builder.build(); RequestContext ctx = new RequestContext(req, builder.getTransform()); List<Grouping> grpList = builder.getRequestList(); for (Grouping grp : grpList) { int grpId = map.size(); grp.setId(grpId); map.put(grpId, grp); ctx.idList.add(grpId); } return ctx; }
private Hit convertVdsHit(String summaryClass, VdsHit grpHit) { FastHit ret = new FastHit(); ret.setRelevance(grpHit.getRank()); if (grpHit.getSummary().getData().length > 0) { GroupingListHit ctxHit = (GroupingListHit)grpHit.getContext(); if (ctxHit == null) { throw new NullPointerException("Hit has no context."); } DocsumDefinitionSet defs = ctxHit.getDocsumDefinitionSet(); defs.lazyDecode(summaryClass, grpHit.getSummary().getData(), ret); ret.setFilled(summaryClass); ret.setFilled(query.getPresentation().getSummary()); } return ret; } }
/** * Returns whether we need to send the query when fetching summaries. * This is necessary if the query requests summary features or dynamic snippeting */ public boolean summaryNeedsQuery(Query query) { if (query.getRanking().getQueryCache()) return false; // Query is cached in backend DocumentDatabase documentDb = getDocumentDatabase(query); // Needed to generate a dynamic summary? DocsumDefinition docsumDefinition = documentDb.getDocsumDefinitionSet().getDocsum(query.getPresentation().getSummary()); if (docsumDefinition.isDynamic()) return true; // Needed to generate ranking features? RankProfile rankProfile = documentDb.rankProfiles().get(query.getRanking().getProfile()); if (rankProfile == null) return true; // stay safe if (rankProfile.hasSummaryFeatures()) return true; if (query.getRanking().getListFeatures()) return true; // (Don't just add other checks here as there is a return false above) return false; }
/** * Fills the result if it is not already filled for the given summary class. * See the fill method. */ public final void ensureFilled(Result result, String summaryClass, Execution execution) { if (summaryClass == null) summaryClass = result.getQuery().getPresentation().getSummary(); if ( ! result.isFilled(summaryClass)) { fill(result, summaryClass, execution); } else { int fillRejectTraceAt = 3; if (result.getQuery().getTraceLevel() >= fillRejectTraceAt) result.getQuery().trace("Ignoring fill(" + summaryClass + "): " + ( result.hits().getFilled() == null ? "Hits are unfillable" : "Hits already filled" ) + ": result.hits().getFilled()=" + result.hits().getFilled(), fillRejectTraceAt); } }
private Result cacheLookupFirstPhase(CacheKey key, QueryPacketData queryPacketData, Query query, int offset, int hits, String summaryClass) { PacketWrapper packetWrapper = cacheControl.lookup(key, query); if (packetWrapper == null) return null; // Check if the cache entry contains the requested hits List<DocumentInfo> documents = packetWrapper.getDocuments(offset, hits); if (documents == null) return null; if (query.getPresentation().getSummary() == null) query.getPresentation().setSummary(getDefaultDocsumClass()); Result result = new Result(query); QueryResultPacket resultPacket = packetWrapper.getFirstResultPacket(); addMetaInfo(query, queryPacketData, resultPacket, result); if (packetWrapper.getNumPackets() == 0) addUnfilledHits(result, documents, true, queryPacketData, key, packetWrapper.distributionKey()); else addCachedHits(result, packetWrapper, summaryClass, documents); return result; }
/** * Returns a cached result, or null if no result was cached for this key * * @param cacheKey the cache key created from the query packet * @param queryPacketData a serialization of the query, to avoid having to recompute this, or null if not available * @param query the query, used for tracing, lookup of result window and result creation */ private Result getCached(CacheKey cacheKey, QueryPacketData queryPacketData, Query query) { if (query.getTraceLevel() >= 6) { query.trace("Cache key hash: " + cacheKey.hashCode(), 6); if (query.getTraceLevel() >= 8) { query.trace("Cache key: " + HexDump.toHexString(cacheKey.getCopyOfFullKey()), 8); } } Result result = cacheLookupFirstPhase(cacheKey, queryPacketData, query, query.getOffset(), query.getHits(), query.getPresentation().getSummary()); if (result == null) return null; if (isLoggingFine()) { getLogger().fine("Result retrieved from cache: " + result); } if (query.getTraceLevel() >= 1) { query.trace(getName() + " cached response: " + result, false, 1); } result.trace(getName()); return result; }
/** Used from container SDK, for internal use only */ public Result searchAndFill(Query query, Chain<? extends Searcher> searchChain, SearchChainRegistry registry) { Result errorResult = validateQuery(query); if (errorResult != null) return errorResult; Renderer<Result> renderer = rendererRegistry.getRenderer(query.getPresentation().getRenderer()); // docsumClass null means "unset", so we set it (it might be null // here too in which case it will still be "unset" after we set it :-) if (query.getPresentation().getSummary() == null && renderer instanceof com.yahoo.search.rendering.Renderer) query.getPresentation().setSummary(((com.yahoo.search.rendering.Renderer) renderer).getDefaultSummaryClass()); Execution execution = new Execution(searchChain, new Execution.Context(registry, indexFacts, specialTokens, rendererRegistry, linguistics)); query.getModel().setExecution(execution); execution.trace().setForceTimestamps(query.properties().getBoolean(FORCE_TIMESTAMPS, false)); if (query.properties().getBoolean(DETAILED_TIMING_LOGGING, false)) { // check and set (instead of set directly) to avoid overwriting stuff from prepareForBreakdownAnalysis() execution.context().setDetailedDiagnostics(true); } Result result = execution.search(query); ensureQuerySet(result, query); execution.fill(result, result.getQuery().getPresentation().getSummary()); traceExecutionTimes(query, result); traceVespaVersion(query); traceRequestAttributes(query); return result; }
@Override public Result doSearch2(Query query, QueryPacket queryPacket, CacheKey cacheKey, Execution execution) { if (dispatcher.searchCluster().groupSize() == 1) forceSinglePassGrouping(query); try(SearchInvoker invoker = getSearchInvoker(query)) { Result result = invoker.search(query, queryPacket, cacheKey, execution); if (query.properties().getBoolean(Ranking.RANKFEATURES, false)) { // There is currently no correct choice for which // summary class we want to fetch at this point. If we // fetch the one selected by the user it may not // contain the data we need. If we fetch the default // one we end up fetching docsums twice unless the // user also requested the default one. fill(result, query.getPresentation().getSummary(), execution); // ARGH } return result; } catch (TimeoutException e) { return new Result(query,ErrorMessage.createTimeout(e.getMessage())); } catch (IOException e) { Result result = new Result(query); if (query.getTraceLevel() >= 1) query.trace(getName() + " error response: " + result, false, 1); result.hits().addError(ErrorMessage.createBackendCommunicationError(getName() + " failed: "+ e.getMessage())); return result; } }
getLogger().finest("got query packet. " + "docsumClass=" + query.getPresentation().getSummary()); if (query.getPresentation().getSummary() == null) query.getPresentation().setSummary(searcher.getDefaultDocsumClass());
resultSource = search(query.clone(), execution, nextOffset, hitsToRequest); String summaryClass = (collapseSummary == null) ? query.getPresentation().getSummary() : collapseSummary; fill(resultSource, summaryClass, execution); collapse(result, knownCollapses, resultSource, collapseField, collapseSize);
params.setLibraryParameter("querystackcount", String.valueOf(ed.getReturned())); params.setLibraryParameter("searchcluster", searchCluster.getBytes()); if (query.getPresentation().getSummary() != null) { params.setLibraryParameter("summaryclass", query.getPresentation().getSummary()); } else { params.setLibraryParameter("summaryclass", "default");
dedupField, groupingHits, query.getPresentation().getSummary(), sorting));
query.getPresentation().getSummary(), ", default docsum class=", getDefaultDocsumClass()); if (query.getPresentation().getSummary() == null) { lazyTrace(query, 6, "doSearch2(): No summary class specified in query, using default: ", lazyTrace(query, 6, "doSearch2(): Summary class has been specified in query: ", query.getPresentation().getSummary()); if (result.isFilled(query.getPresentation().getSummary())) { lazyTrace(query, 8, "Result is filled for summary class ", query.getPresentation().getSummary()); } else { lazyTrace(query, 8, "Result is not filled for summary class ", query.getPresentation().getSummary()); FillHitsResult fillHitsResult = fillHits(result, summaryPackets, query.getPresentation().getSummary()); skippedHits = fillHitsResult.skippedHits; if (fillHitsResult.error != null) {