use of com.yahoo.search.Result in project vespa by vespa-engine.
the class ValidateSortingSearcher method search.
@Override
public Result search(Query query, Execution execution) {
if (indexingMode != QrSearchersConfig.Searchcluster.Indexingmode.STREAMING) {
ErrorMessage e = validate(query);
if (e != null) {
Result r = new Result(query);
r.hits().addError(e);
return r;
}
}
return execution.search(query);
}
use of com.yahoo.search.Result in project vespa by vespa-engine.
the class RecallSearcher method search.
@Override
public com.yahoo.search.Result search(Query query, Execution execution) {
String recall = query.properties().getString(recallName);
if (recall == null)
return execution.search(query);
AnyParser parser = new AnyParser(ParserEnvironment.fromExecutionContext(execution.context()));
QueryTree root = parser.parse(Parsable.fromQueryModel(query.getModel()).setQuery("foo").setFilter(recall));
String err;
if (root.getRoot() instanceof NullItem) {
err = "Failed to parse recall parameter.";
} else if (!(root.getRoot() instanceof CompositeItem)) {
err = "Expected CompositeItem root node, got " + root.getClass().getSimpleName() + ".";
} else if (hasRankItem(root.getRoot())) {
query.getModel().getQueryTree().setRoot(root.getRoot());
err = "Recall contains at least one rank item.";
} else {
WordItem placeholder = findOrigWordItem(root.getRoot(), "foo");
if (placeholder == null) {
err = "Could not find placeholder workQuery root.";
} else {
updateFilterTerms(root);
CompositeItem parent = placeholder.getParent();
parent.setItem(parent.getItemIndex(placeholder), query.getModel().getQueryTree().getRoot());
query.getModel().getQueryTree().setRoot(root.getRoot());
query.trace("ANDed recall tree with root workQuery node.", true, 3);
return execution.search(query);
}
}
return new Result(query, ErrorMessage.createInvalidQueryParameter(err));
}
use of com.yahoo.search.Result in project vespa by vespa-engine.
the class CachingSearcher method search.
public Result search(com.yahoo.search.Query query, Execution execution) {
if (query.getNoCache()) {
return execution.search(query);
}
QueryCacheKey queryKey = new QueryCacheKey(query);
Result cachedResult = cache.get(queryKey);
if (cachedResult != null) {
cacheHit();
return cachedResult;
}
cacheMiss();
// Need a copy, as cache hash key later on, maybe.
Query originalQuery = query.clone();
Result result = execution.search(query);
execution.fill(result);
if (!noCacheWrite(query)) {
// Because the query member has changed state
queryKey.setQuery(originalQuery);
cache.put(queryKey, result);
}
return result;
}
use of com.yahoo.search.Result in project vespa by vespa-engine.
the class FieldCollapsingSearcher method search.
/**
* First fetch result from the next searcher in the chain.
* If collapse is active, do collapsing.
* Otherwise, act as a simple pass through
*/
public Result search(com.yahoo.search.Query query, Execution execution) {
String collapseField = query.properties().getString(collapsefield);
if (collapseField == null)
return execution.search(query);
int collapseSize = query.properties().getInteger(collapsesize, defaultCollapseSize);
query.properties().set(collapse, "0");
int hitsToRequest = query.getHits() != 0 ? (int) Math.ceil((query.getOffset() + query.getHits() + 1) * extraFactor) : 0;
int nextOffset = 0;
int hitsAfterCollapse;
boolean moreHitsAvailable = true;
Map<String, Integer> knownCollapses = new java.util.HashMap<>();
Result result = new Result(query);
int performedQueries = 0;
Result resultSource;
String collapseSummary = query.properties().getString(collapseSummaryName);
do {
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);
hitsAfterCollapse = result.getHitCount();
if (resultSource.getTotalHitCount() < (hitsToRequest + nextOffset)) {
// the searcher downstream has no more hits
moreHitsAvailable = false;
}
nextOffset += hitsToRequest;
if (hitsAfterCollapse < query.getOffset() + query.getHits()) {
hitsToRequest = (int) Math.ceil(hitsToRequest * extraFactor);
}
++performedQueries;
} while (hitsToRequest != 0 && (hitsAfterCollapse < query.getOffset() + query.getHits()) && moreHitsAvailable && (performedQueries <= maxQueries));
// Set correct meta information
result.mergeWith(resultSource);
// Keep only (offset,.. offset+hits) hits
result.hits().trim(query.getOffset(), query.getHits());
// Mark query as query with collapsing
query.properties().set(collapse, "1");
return result;
}
use of com.yahoo.search.Result in project vespa by vespa-engine.
the class FederationSearcher method fill.
@Override
public void fill(Result result, String summaryClass, Execution execution) {
UniqueExecutionsToResults uniqueExecutionsToResults = new UniqueExecutionsToResults();
addResultsToFill(result.hits(), result, summaryClass, uniqueExecutionsToResults);
Set<Entry<Chain<Searcher>, Map<Query, Result>>> resultsForAllChains = uniqueExecutionsToResults.resultsToFill.entrySet();
int numberOfCallsToFillNeeded = 0;
for (Entry<Chain<Searcher>, Map<Query, Result>> resultsToFillForAChain : resultsForAllChains) {
numberOfCallsToFillNeeded += resultsToFillForAChain.getValue().size();
}
List<Pair<Result, FutureResult>> futureFilledResults = new ArrayList<>();
for (Entry<Chain<Searcher>, Map<Query, Result>> resultsToFillForAChain : resultsForAllChains) {
Chain<Searcher> chain = resultsToFillForAChain.getKey();
Execution chainExecution = (chain == null) ? execution : new Execution(chain, execution.context());
for (Entry<Query, Result> resultsToFillForAChainAndQuery : resultsToFillForAChain.getValue().entrySet()) {
Result resultToFill = resultsToFillForAChainAndQuery.getValue();
if (numberOfCallsToFillNeeded == 1) {
chainExecution.fill(resultToFill, summaryClass);
propagateErrors(resultToFill, result);
} else {
AsyncExecution asyncFill = new AsyncExecution(chainExecution);
futureFilledResults.add(new Pair<>(resultToFill, asyncFill.fill(resultToFill, summaryClass)));
}
}
}
for (Pair<Result, FutureResult> futureFilledResult : futureFilledResults) {
// futureFilledResult is a pair of a result to be filled and the future in which that same result is filled
Optional<Result> filledResult = futureFilledResult.getSecond().getIfAvailable(result.getQuery().getTimeLeft(), TimeUnit.MILLISECONDS);
if (filledResult.isPresent()) {
// fill completed
propagateErrors(filledResult.get(), result);
} else {
// fill timed out: Remove these hits as they are incomplete and may cause a race when accessed later
result.hits().addError(futureFilledResult.getSecond().createTimeoutError());
for (Iterator<Hit> i = futureFilledResult.getFirst().hits().unorderedDeepIterator(); i.hasNext(); ) {
// Note that some of these hits may be filled, but as the fill thread may still be working on them
// and we do not synchronize with it we need to discard all
Hit removed = result.hits().remove(i.next().getId());
}
}
}
}
Aggregations