if (query.getRanking().hasRankProfile()) { s.append(" rankprofile[") .append(query.getRanking().getProfile()) .append("]"); if (query.getRanking().getFreshness() != null) { s.append(" freshness=") .append(query.getRanking().getFreshness().getRefTime()); if (query.getRanking().getSorting() != null) { s.append(" sortspec=") .append(query.getRanking().getSorting().fieldOrders().toString()); if (query.getRanking().getLocation() != null) { s.append(" location=") .append(query.getRanking().getLocation().toString()); if (query.getRanking().getQueryCache()) { s.append(" ranking.queryCache=true"); if (query.getGroupingSessionCache() || query.getRanking().getQueryCache()) { s.append(" sessionId=").append(query.getSessionId()); if ( ! query.getRanking().getProperties().isEmpty()) { s.append(" rankproperties=") .append(query.getRanking().getProperties().toString()); if ( ! query.getRanking().getFeatures().isEmpty()) { s.append(" rankfeatures=")
/** * 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; }
private void setDegradation(Query query) { query.trace("Using sorting degrading for performance - totalHits will be wrong. " + "Turn off with sorting.degrading=false.", 2); Sorting.FieldOrder primarySort = query.getRanking().getSorting().fieldOrders().get(0); // ensured above MatchPhase matchPhase = query.getRanking().getMatchPhase(); matchPhase.setAttribute(primarySort.getFieldName()); matchPhase.setAscending(primarySort.getSortOrder() == Sorting.Order.ASCENDING); if (matchPhase.getMaxHits() == null) matchPhase.setMaxHits(decideDefaultMaxHits(query)); }
private int getFeatureInt(boolean sendSessionId) { int features = QF_PARSEDQUERY | QF_RANKP; // this bitmask means "parsed query" in query packet. // And rank properties. Both are always present features |= (query.getRanking().getSorting() != null) ? QF_SORTSPEC : 0; features |= (query.getRanking().getLocation() != null) ? QF_LOCATION : 0; features |= (query.hasEncodableProperties()) ? QF_PROPERTIES : 0; features |= GroupingExecutor.hasGroupingList(query) ? QF_GROUPSPEC : 0; features |= (sendSessionId) ? QF_SESSIONID : 0; return features; }
public boolean hasEncodableProperties() { if ( ! ranking.getProperties().isEmpty()) return true; if ( ! ranking.getFeatures().isEmpty()) return true; if ( ranking.getFreshness() != null) return true; if ( model.getSearchPath() != null) return true; if ( model.getDocumentDb() != null) return true; if ( presentation.getHighlight() != null && ! presentation.getHighlight().getHighlightItems().isEmpty()) return true; return false; }
private void encodeQuery(ByteBuffer buffer) { Item.putString(query.getRanking().getProfile(), buffer); buffer.putInt(QueryPacket.getQueryFlags(query)); encodeSummaryClass(buffer); query.encodeAsProperties(buffer, sendQuery); if (sendQuery) { // The stack must be resubmitted to generate dynamic docsums int itemCountPosition = buffer.position(); buffer.putInt(0); int dumpLengthPosition = buffer.position(); buffer.putInt(0); int count = query.encode(buffer); buffer.putInt(itemCountPosition, count); buffer.putInt(dumpLengthPosition, buffer.position() - dumpLengthPosition - 4); } if (query.getRanking().getLocation() != null) { int locationLengthPosition = buffer.position(); buffer.putInt(0); int locationLength = query.getRanking().getLocation().encode(buffer); buffer.putInt(locationLengthPosition, locationLength); } }
Ranking ranking = query.getRanking(); if (key.size() == 2) { if (key.last().equals(Ranking.LOCATION)) return ranking.getLocation(); if (key.last().equals(Ranking.PROFILE)) return ranking.getProfile(); if (key.last().equals(Ranking.SORTING)) return ranking.getSorting(); if (key.last().equals(Ranking.FRESHNESS)) return ranking.getFreshness(); if (key.last().equals(Ranking.QUERYCACHE)) return ranking.getQueryCache(); if (key.last().equals(Ranking.LIST_FEATURES)) return ranking.getListFeatures(); MatchPhase matchPhase = ranking.getMatchPhase(); if (key.last().equals(MatchPhase.ATTRIBUTE)) return matchPhase.getAttribute(); if (key.last().equals(MatchPhase.ASCENDING)) return matchPhase.getAscending(); if (key.last().equals(MatchPhase.MAX_FILTER_COVERAGE)) return matchPhase.getMaxFilterCoverage(); } else if (key.size() >= 4 && key.get(2).equals(Ranking.DIVERSITY)) { Diversity diversity = ranking.getMatchPhase().getDiversity(); if (key.size() == 4) { if (key.last().equals(Diversity.ATTRIBUTE)) return diversity.getAttribute(); SoftTimeout soft = ranking.getSoftTimeout(); if (key.last().equals(SoftTimeout.ENABLE)) return soft.getEnable(); if (key.last().equals(SoftTimeout.FACTOR)) return soft.getFactor(); Matching matching = ranking.getMatching(); if (key.last().equals(Matching.TERMWISELIMIT)) return matching.getTermwiseLimit(); if (key.last().equals(Matching.NUMTHREADSPERSEARCH)) return matching.getNumThreadsPerSearch(); if (key.get(1).equals(Ranking.FEATURES)) return ranking.getFeatures().getObject(key.rest().rest().toString()); if (key.get(1).equals(Ranking.PROPERTIES)) return ranking.getProperties().get(key.rest().rest().toString());
if (key.size()==2) { if (key.last().equals(Ranking.LOCATION)) ranking.setLocation(asString(value,"")); else if (key.last().equals(Ranking.PROFILE)) ranking.setProfile(asString(value,"")); else if (key.last().equals(Ranking.SORTING)) ranking.setSorting(asString(value,"")); else if (key.last().equals(Ranking.FRESHNESS)) ranking.setFreshness(asString(value, "")); else if (key.last().equals(Ranking.QUERYCACHE)) ranking.setQueryCache(asBoolean(value, false)); else if (key.last().equals(Ranking.LIST_FEATURES)) ranking.setListFeatures(asBoolean(value,false)); MatchPhase matchPhase = ranking.getMatchPhase(); if (key.last().equals(MatchPhase.ATTRIBUTE)) { matchPhase.setAttribute(asString(value, null)); Diversity diversity = ranking.getMatchPhase().getDiversity(); if (key.last().equals(Diversity.ATTRIBUTE)) { diversity.setAttribute(asString(value, null)); SoftTimeout soft = ranking.getSoftTimeout(); if (key.last().equals(SoftTimeout.ENABLE)) soft.setEnable(asBoolean(value, true)); if (key.last().equals(SoftTimeout.FACTOR)) soft.setFactor(asDouble(value, null)); Matching matching = ranking.getMatching(); if (key.last().equals(Matching.TERMWISELIMIT)) matching.setTermwiselimit(asDouble(value, 1.0)); if (key.last().equals(Matching.NUMTHREADSPERSEARCH)) matching.setNumThreadsPerSearch(asInteger(value, 1));
private void setRankingFeature(Query query, String key, Object value) { if (value instanceof Tensor) query.getRanking().getFeatures().put(key, (Tensor)value); else query.getRanking().getFeatures().put(key, asString(value, "")); }
/** * Encodes properties of this query. * * @param buffer the buffer to encode to * @param encodeQueryData true to encode all properties, false to only include session information, not actual query data * @return the encoded length */ public int encodeAsProperties(ByteBuffer buffer, boolean encodeQueryData) { // Make sure we don't encode anything here if we have turned the property feature off // Due to sendQuery we sometimes end up turning this feature on and then encoding a 0 int as the number of // property maps - that's ok (probably we should simplify by just always turning the feature on) if (! hasEncodableProperties()) return 0; int start = buffer.position(); int mapCountPosition = buffer.position(); buffer.putInt(0); // map count will go here int mapCount = 0; // TODO: Push down mapCount += ranking.getProperties().encode(buffer, encodeQueryData); if (encodeQueryData) mapCount += ranking.getFeatures().encode(buffer); // TODO: Push down if (encodeQueryData && presentation.getHighlight() != null) mapCount += MapEncoder.encodeStringMultiMap(Highlight.HIGHLIGHTTERMS, presentation.getHighlight().getHighlightTerms(), buffer); // TODO: Push down if (encodeQueryData) mapCount += MapEncoder.encodeSingleValue("model", "searchpath", model.getSearchPath(), buffer); mapCount += MapEncoder.encodeSingleValue(DocumentDatabase.MATCH_PROPERTY, DocumentDatabase.SEARCH_DOC_TYPE_KEY, model.getDocumentDb(), buffer); mapCount += MapEncoder.encodeMap("caches", createCacheSettingMap(), buffer); buffer.putInt(mapCountPosition, mapCount); return buffer.position() - start; }
final int relativeZero = buffer.position(); boolean sendSessionKey = query.getGroupingSessionCache() || query.getRanking().getQueryCache(); int featureFlag = getFeatureInt(sendSessionKey); buffer.putInt(featureFlag); buffer.putInt(getFlagInt()); int startOfFieldToSave = buffer.position(); Item.putString(query.getRanking().getProfile(), buffer); queryPacketData.setRankProfile(buffer, startOfFieldToSave); int sortSpecLengthPosition=buffer.position(); buffer.putInt(0); int sortSpecLength = query.getRanking().getSorting().encode(buffer); buffer.putInt(sortSpecLengthPosition, sortSpecLength); int locationLengthPosition=buffer.position(); buffer.putInt(0); int locationLength= query.getRanking().getLocation().encode(buffer); buffer.putInt(locationLengthPosition, locationLength); queryPacketData.setLocation(buffer, startOfFieldToSave);
public void encodeBody(ByteBuffer buffer) { setFieldsFromHits(); boolean useQueryCache = query.getRanking().getQueryCache(); query.getRanking().getProperties().put(sessionIdKey, query.getSessionId().toString()); if (query.getRanking().getLocation() != null) features |= GDF_LOCATION; if (query.hasEncodableProperties())
params.setLibraryParameter("rankprofile", query.getRanking().getProfile()); params.setLibraryParameter("allowslimedocsums", "true"); params.setLibraryParameter("queryflags", String.valueOf(getQueryFlags(query))); if (query.getRanking().getLocation() != null) { buf.clear(); query.getRanking().getLocation().encode(buf); buf.flip(); byte[] af = new byte [buf.remaining()]; if (query.getRanking().getSorting() != null) { encodeQueryData(query, 3, ed); params.setLibraryParameter("sort", ed.getEncodedData());
return execution.search(query); // Nothing to do if (query.getRanking().getLocation() != null) { query.getRanking().setLocation(loc); return execution.search(query);
public Optional<FillInvoker> getFillInvoker(Query query, VespaBackEndSearcher searcher, DocumentDatabase documentDb) { if (query.properties().getBoolean(dispatchSummaries, true) && ! searcher.summaryNeedsQuery(query) && query.getRanking().getLocation() == null && ! searcher.getCacheControl().useCache(query)) { return Optional.of(new RpcFillInvoker(this, documentDb)); } else { return Optional.empty(); } }
private ErrorMessage validate(Query query) { String attribute = query.getRanking().getMatchPhase().getAttribute(); if ( attribute != null && ! validMatchPhaseAttributes.contains(attribute) ) { return ErrorMessage.createInvalidQueryParameter("The attribute '" + attribute + "' is not available for match-phase. " + "It must be a single value numeric attribute with fast-search."); } attribute = query.getRanking().getMatchPhase().getDiversity().getAttribute(); if (attribute != null && ! validDiversityAttributes.contains(attribute)) { return ErrorMessage.createInvalidQueryParameter("The attribute '" + attribute + "' is not available for match-phase diversification. " + "It must be a single value numeric or string attribute."); } return null; }
static void removeEmptySummaryFeatureFields(Result result) { // TODO: Move to some searcher in Vespa backend search chains if ( ! result.hits().getQuery().getRanking().getListFeatures()) for (Iterator<Hit> i = result.hits().unorderedIterator(); i.hasNext();) i.next().removeField(Hit.RANKFEATURES_FIELD); }
static int getQueryFlags(Query query) { int flags = 0; boolean requestCoverage=true; // Always request coverage information flags |= 0; // was collapse flags |= query.properties().getBoolean(Model.ESTIMATE) ? 0x00000080 : 0; flags |= (query.getRanking().getFreshness() != null) ? 0x00002000 : 0; flags |= requestCoverage ? 0x00008000 : 0; flags |= query.getNoCache() ? 0x00010000 : 0; flags |= 0x00020000; // was PARALLEL flags |= query.properties().getBoolean(Ranking.RANKFEATURES,false) ? 0x00040000 : 0; return flags; }
/** Returns whether the given query is equal to this */ @Override public boolean equals(Object other) { if (this == other) return true; if ( ! (other instanceof Query)) return false; Query q = (Query) other; if (getOffset() != q.getOffset()) return false; if (getHits() != q.getHits()) return false; if ( ! getPresentation().equals(q.getPresentation())) return false; if ( ! getRanking().equals(q.getRanking())) return false; if ( ! getModel().equals(q.getModel())) return false; // TODO: Compare property settings return true; }
public static void addNativeQueryProfileTypesTo(QueryProfileTypeRegistry registry) { // Add modifiable copies to allow query profile types in this to add to these registry.register(Query.getArgumentType().unfrozen()); registry.register(Ranking.getArgumentType().unfrozen()); registry.register(Model.getArgumentType().unfrozen()); registry.register(Select.getArgumentType().unfrozen()); registry.register(Presentation.getArgumentType().unfrozen()); registry.register(DefaultProperties.argumentType.unfrozen()); }