use of com.yahoo.search.query.profile.compiled.CompiledQueryProfile in project vespa by vespa-engine.
the class SearchHandler method handleBody.
private HttpSearchResponse handleBody(HttpRequest request) {
// Find query profile
String queryProfileName = request.getProperty("queryProfile");
CompiledQueryProfile queryProfile = queryProfileRegistry.findQueryProfile(queryProfileName);
boolean benchmarkOutput = VespaHeaders.benchmarkOutput(request);
// Create query
Query query = new Query(request, queryProfile);
boolean benchmarkCoverage = VespaHeaders.benchmarkCoverage(benchmarkOutput, request.getJDiscRequest().headers());
// Find and execute search chain if we have a valid query
String invalidReason = query.validate();
Chain<Searcher> searchChain = null;
String searchChainName = null;
if (invalidReason == null) {
Tuple2<String, Chain<Searcher>> nameAndChain = resolveChain(query.properties().getString(Query.SEARCH_CHAIN));
searchChainName = nameAndChain.first;
searchChain = nameAndChain.second;
}
// Create the result
Result result;
if (invalidReason != null) {
result = new Result(query, ErrorMessage.createIllegalQuery(invalidReason));
} else if (queryProfile == null && queryProfileName != null) {
result = new Result(query, ErrorMessage.createIllegalQuery("Could not resolve query profile '" + queryProfileName + "'"));
} else if (searchChain == null) {
result = new Result(query, ErrorMessage.createInvalidQueryParameter("No search chain named '" + searchChainName + "' was found"));
} else {
String pathAndQuery = UriTools.rawRequest(request.getUri());
result = search(pathAndQuery, query, searchChain, searchChainRegistry);
}
Renderer renderer;
if (result.getTemplating().usesDefaultTemplate()) {
renderer = toRendererCopy(query.getPresentation().getRenderer());
// pre-Vespa 6 Result.getEncoding() expects this to be set. TODO: Remove
result.getTemplating().setRenderer(renderer);
} else {
// somebody explicitly assigned a old style template
renderer = perRenderingCopy(result.getTemplating().getRenderer());
}
// Transform result to response
HttpSearchResponse response = new HttpSearchResponse(getHttpResponseStatus(request, result), result, query, renderer);
if (hostResponseHeaderKey.isPresent())
response.headers().add(hostResponseHeaderKey.get(), selfHostname);
if (benchmarkOutput)
VespaHeaders.benchmarkOutput(response.headers(), benchmarkCoverage, response.getTiming(), response.getHitCounts(), getErrors(result), response.getCoverage());
return response;
}
use of com.yahoo.search.query.profile.compiled.CompiledQueryProfile in project vespa by vespa-engine.
the class QueryProfileCompiler method compile.
public static CompiledQueryProfile compile(QueryProfile in, CompiledQueryProfileRegistry registry) {
DimensionalMap.Builder<CompoundName, Object> values = new DimensionalMap.Builder<>();
DimensionalMap.Builder<CompoundName, QueryProfileType> types = new DimensionalMap.Builder<>();
DimensionalMap.Builder<CompoundName, Object> references = new DimensionalMap.Builder<>();
DimensionalMap.Builder<CompoundName, Object> unoverridables = new DimensionalMap.Builder<>();
// Resolve values for each existing variant and combine into a single data structure
Set<DimensionBindingForPath> variants = new HashSet<>();
collectVariants(CompoundName.empty, in, DimensionBinding.nullBinding, variants);
// if this contains no variants
variants.add(new DimensionBindingForPath(DimensionBinding.nullBinding, CompoundName.empty));
if (log.isLoggable(Level.FINE))
log.fine("Compiling " + in.toString() + " having " + variants.size() + " variants");
int i = 0;
for (DimensionBindingForPath variant : variants) {
if (log.isLoggable(Level.FINER))
log.finer(" Compiling variant " + i++ + ": " + variant);
for (Map.Entry<String, Object> entry : in.listValues(variant.path(), variant.binding().getContext(), null).entrySet()) values.put(variant.path().append(entry.getKey()), variant.binding(), entry.getValue());
for (Map.Entry<CompoundName, QueryProfileType> entry : in.listTypes(variant.path(), variant.binding().getContext()).entrySet()) types.put(variant.path().append(entry.getKey()), variant.binding(), entry.getValue());
for (CompoundName reference : in.listReferences(variant.path(), variant.binding().getContext())) // Used as a set; value is ignored
references.put(variant.path().append(reference), variant.binding(), Boolean.TRUE);
for (CompoundName name : in.listUnoverridable(variant.path(), variant.binding().getContext())) // Used as a set; value is ignored
unoverridables.put(variant.path().append(name), variant.binding(), Boolean.TRUE);
}
return new CompiledQueryProfile(in.getId(), in.getType(), values.build(), types.build(), references.build(), unoverridables.build(), registry);
}
use of com.yahoo.search.query.profile.compiled.CompiledQueryProfile in project vespa by vespa-engine.
the class QueryProfileProperties method set.
/**
* Sets a value in this query profile
*
* @throws IllegalArgumentException if this property cannot be set in the wrapped query profile
*/
@Override
public void set(CompoundName name, Object value, Map<String, String> context) {
// TODO: Refactor
try {
name = unalias(name, context);
if (context == null)
context = Collections.emptyMap();
if (!profile.isOverridable(name, context))
return;
// Check runtime references
Pair<CompoundName, CompiledQueryProfile> runtimeReference = findReference(name);
if (runtimeReference != null && !runtimeReference.getSecond().isOverridable(name.rest(runtimeReference.getFirst().size()), context))
return;
// Check types
if (!profile.getTypes().isEmpty()) {
for (int i = 0; i < name.size(); i++) {
QueryProfileType type = profile.getType(name.first(i), context);
if (type == null)
continue;
String localName = name.get(i);
FieldDescription fieldDescription = type.getField(localName);
if (fieldDescription == null && type.isStrict())
throw new IllegalArgumentException("'" + localName + "' is not declared in " + type + ", and the type is strict");
if (i == name.size() - 1 && fieldDescription != null) {
// at the end of the path, check the assignment type
value = fieldDescription.getType().convertFrom(value, profile.getRegistry());
if (value == null)
throw new IllegalArgumentException("'" + value + "' is not a " + fieldDescription.getType().toInstanceDescription());
}
}
}
if (value instanceof String && value.toString().startsWith("ref:")) {
if (profile.getRegistry() == null)
throw new IllegalArgumentException("Runtime query profile references does not work when the " + "QueryProfileProperties are constructed without a registry");
String queryProfileId = value.toString().substring(4);
value = profile.getRegistry().findQueryProfile(queryProfileId);
if (value == null)
throw new IllegalArgumentException("Query profile '" + queryProfileId + "' is not found");
}
if (value instanceof CompiledQueryProfile) {
// this will be due to one of the two clauses above
if (references == null)
references = new ArrayList<>();
// references set later has precedence - put first
references.add(0, new Pair<>(name, (CompiledQueryProfile) value));
} else {
if (values == null)
values = new HashMap<>();
values.put(name, value);
}
} catch (IllegalArgumentException e) {
// TODO: Nest instead
throw new IllegalArgumentException("Could not set '" + name + "' to '" + value + "': " + e.getMessage());
}
}
use of com.yahoo.search.query.profile.compiled.CompiledQueryProfile in project vespa by vespa-engine.
the class QueryProfileFieldType method convertFrom.
@Override
public CompiledQueryProfile convertFrom(Object object, CompiledQueryProfileRegistry registry) {
String profileId = object.toString();
if (profileId.startsWith("ref:"))
profileId = profileId.substring("ref:".length());
CompiledQueryProfile profile = registry.getComponent(profileId);
if (profile == null)
return null;
if (type != null && !type.equals(profile.getType()))
return null;
return profile;
}
use of com.yahoo.search.query.profile.compiled.CompiledQueryProfile in project vespa by vespa-engine.
the class Query method traceProperties.
/**
* Traces how properties was resolved and from where. Done after the fact to avoid special handling
* of tracelevel, which is the property deciding whether this needs to be done
*/
private void traceProperties() {
if (traceLevel == 0)
return;
CompiledQueryProfile profile = null;
QueryProfileProperties profileProperties = properties().getInstance(QueryProfileProperties.class);
if (profileProperties != null)
profile = profileProperties.getQueryProfile();
if (profile == null)
trace("No query profile is used", false, 1);
else
trace("Using " + profile.toString(), false, 1);
if (traceLevel < 4)
return;
StringBuilder b = new StringBuilder("Resolved properties:\n");
Set<String> mentioned = new HashSet<>();
for (Map.Entry<String, String> requestProperty : requestProperties().entrySet()) {
Object resolvedValue = properties().get(requestProperty.getKey(), requestProperties());
if (resolvedValue == null && requestProperty.getKey().equals("queryProfile"))
resolvedValue = requestProperty.getValue();
b.append(requestProperty.getKey());
b.append("=");
// (may be null)
b.append(String.valueOf(resolvedValue));
b.append(" (");
if (profile != null && !profile.isOverridable(new CompoundName(requestProperty.getKey()), requestProperties()))
b.append("value from query profile - unoverridable, ignoring request value");
else
b.append("value from request");
b.append(")\n");
mentioned.add(requestProperty.getKey());
}
if (profile != null) {
appendQueryProfileProperties(profile, mentioned, b);
}
trace(b.toString(), false, 4);
}
Aggregations