use of org.opengrok.suggest.query.SuggesterQuery in project OpenGrok by OpenGrok.
the class SuggesterQueryDataParser method parse.
/**
* Parses the {@link SuggesterQueryData}.
* @param data data to parse
* @return parsed data for the suggester use
* @throws ParseException could not parse the search data into a valid {@link Query}
*/
public static SuggesterData parse(final SuggesterQueryData data) throws ParseException {
List<String> projectList = data.getProjects().stream().filter(p -> RuntimeEnvironment.getInstance().getProjectNames().contains(p)).collect(Collectors.toList());
Map<String, String> fieldQueries = getFieldQueries(data);
ProcessedQueryData queryData = processQuery(fieldQueries.get(data.getField()), data.getCaretPosition());
fieldQueries.put(data.getField(), queryData.query);
SuggesterQueryBuilder builder = new SuggesterQueryBuilder(data.getField(), queryData.identifier);
builder.setFreetext(fieldQueries.get(QueryBuilder.FULL)).setDefs(fieldQueries.get(QueryBuilder.DEFS)).setRefs(fieldQueries.get(QueryBuilder.REFS)).setPath(fieldQueries.get(QueryBuilder.PATH)).setHist(fieldQueries.get(QueryBuilder.HIST)).setType(fieldQueries.get(QueryBuilder.TYPE));
Query query;
try {
query = builder.build();
} catch (ParseException e) {
// the position might be still wrong if the parse error was at the end of the identifier
throw new ParseException(e.getMessage().replaceAll(queryData.identifier, ""));
}
SuggesterQuery suggesterQuery = builder.getSuggesterQuery();
// builder can return the suggester query if it was simple query, we ignore it in that case
if (query.equals(suggesterQuery)) {
query = null;
}
return new SuggesterData(suggesterQuery, projectList, query, builder.getQueryTextWithPlaceholder(), builder.getIdentifier());
}
use of org.opengrok.suggest.query.SuggesterQuery in project OpenGrok by OpenGrok.
the class SuggesterQueryParser method newBooleanClause.
@Override
protected BooleanClause newBooleanClause(final Query q, final BooleanClause.Occur occur) {
BooleanClause bc;
if (q instanceof SuggesterPhraseQuery) {
bc = super.newBooleanClause(((SuggesterPhraseQuery) q).getPhraseQuery(), BooleanClause.Occur.MUST);
suggesterClauses.add(bc);
} else if (q instanceof SuggesterQuery) {
bc = super.newBooleanClause(new MatchAllDocsQuery(), BooleanClause.Occur.MUST);
suggesterClauses.add(bc);
} else if (q instanceof BooleanQuery) {
bc = super.newBooleanClause(q, occur);
for (BooleanClause clause : ((BooleanQuery) q).clauses()) {
if (suggesterClauses.contains(clause)) {
suggesterClauses.add(bc);
}
}
} else {
bc = super.newBooleanClause(q, occur);
}
return bc;
}
use of org.opengrok.suggest.query.SuggesterQuery in project OpenGrok by OpenGrok.
the class SuggesterSearcher method suggest.
/**
* Returns the suggestions for generic {@link SuggesterQuery} (almost all except lone
* {@link org.opengrok.suggest.query.SuggesterPrefixQuery} for which see {@link SuggesterProjectData}).
* @param query query on which the suggestions depend
* @param project name of the project
* @param suggesterQuery query for the suggestions
* @param popularityCounter data structure which contains the number of times the terms were searched for. It is
* used to provide the most popular completion functionality.
* @return suggestions
*/
public List<LookupResultItem> suggest(final Query query, final String project, final SuggesterQuery suggesterQuery, final PopularityCounter popularityCounter) {
List<LookupResultItem> results = new ArrayList<>(resultSize * leafContexts.size());
Query rewrittenQuery = null;
try {
if (query != null) {
rewrittenQuery = query.rewrite(getIndexReader());
}
} catch (IOException e) {
logger.log(Level.WARNING, "Could not rewrite query", e);
return results;
}
for (LeafReaderContext context : this.leafContexts) {
if (interrupted) {
break;
}
try {
results.addAll(suggest(rewrittenQuery, context, project, suggesterQuery, popularityCounter));
} catch (IOException e) {
logger.log(Level.WARNING, "Cannot perform suggester search", e);
}
}
if (results.size() > resultSize) {
return SuggesterUtils.combineResults(results, resultSize);
}
return results;
}
use of org.opengrok.suggest.query.SuggesterQuery in project OpenGrok by OpenGrok.
the class SuggesterSearcher method suggest.
private List<LookupResultItem> suggest(final Query query, final LeafReaderContext leafReaderContext, final String project, final SuggesterQuery suggesterQuery, final PopularityCounter searchCounts) throws IOException {
if (Thread.currentThread().isInterrupted()) {
interrupted = true;
return Collections.emptyList();
}
boolean shouldLeaveOutSameTerms = shouldLeaveOutSameTerms(query, suggesterQuery);
Set<BytesRef> tokensAlreadyIncluded = null;
if (shouldLeaveOutSameTerms) {
tokensAlreadyIncluded = SuggesterUtils.intoTermsExceptPhraseQuery(query).stream().filter(t -> t.field().equals(suggesterQuery.getField())).map(Term::bytes).collect(Collectors.toSet());
}
boolean needsDocumentIds = query != null && !(query instanceof MatchAllDocsQuery);
ComplexQueryData complexQueryData = null;
if (needsDocumentIds) {
complexQueryData = getComplexQueryData(query, leafReaderContext);
if (interrupted) {
return Collections.emptyList();
}
}
Terms terms = leafReaderContext.reader().terms(suggesterQuery.getField());
TermsEnum termsEnum = suggesterQuery.getTermsEnumForSuggestions(terms);
LookupPriorityQueue queue = new LookupPriorityQueue(resultSize);
boolean needPositionsAndFrequencies = needPositionsAndFrequencies(query);
PostingsEnum postingsEnum = null;
BytesRef term = termsEnum.next();
while (term != null) {
if (Thread.currentThread().isInterrupted()) {
interrupted = true;
break;
}
if (needPositionsAndFrequencies) {
postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.POSITIONS | PostingsEnum.FREQS);
} else {
postingsEnum = termsEnum.postings(postingsEnum, PostingsEnum.NONE);
}
int score = 0;
if (!needsDocumentIds) {
score = normalizeDocumentFrequency(termsEnum.docFreq(), numDocs);
} else if (needPositionsAndFrequencies) {
score = getPhraseScore(complexQueryData, leafReaderContext.docBase, postingsEnum);
} else if (complexQueryData != null) {
score = getDocumentFrequency(complexQueryData.documentIds, leafReaderContext.docBase, postingsEnum);
}
if (score > 0) {
if (!shouldLeaveOutSameTerms || !tokensAlreadyIncluded.contains(term)) {
score += searchCounts.get(term) * TERM_ALREADY_SEARCHED_MULTIPLIER;
if (queue.canInsert(score)) {
queue.insertWithOverflow(new LookupResultItem(term.utf8ToString(), project, score));
}
}
}
term = termsEnum.next();
}
return queue.getResult();
}
use of org.opengrok.suggest.query.SuggesterQuery in project OpenGrok by OpenGrok.
the class SuggesterSearcher method getComplexQueryData.
private ComplexQueryData getComplexQueryData(final Query query, final LeafReaderContext leafReaderContext) {
ComplexQueryData data = new ComplexQueryData();
if (query == null || query instanceof SuggesterQuery) {
data.documentIds = new BitIntsHolder(0);
return data;
}
BitIntsHolder documentIds = new BitIntsHolder();
try {
search(query, new Collector() {
@Override
public LeafCollector getLeafCollector(final LeafReaderContext context) {
return new LeafCollector() {
final int docBase = context.docBase;
@Override
public void setScorer(final Scorable scorer) {
if (leafReaderContext == context) {
if (scorer instanceof PhraseScorer) {
data.scorer = (PhraseScorer) scorer;
} else {
try {
// in #setScorer but no better way was found
for (Scorer.ChildScorable childScorer : scorer.getChildren()) {
if (childScorer.child instanceof PhraseScorer) {
data.scorer = (PhraseScorer) childScorer.child;
}
}
} catch (Exception e) {
// ignore
}
}
}
}
@Override
public void collect(int doc) {
if (leafReaderContext == context) {
documentIds.set(docBase + doc);
}
}
};
}
@Override
public ScoreMode scoreMode() {
return ScoreMode.COMPLETE_NO_SCORES;
}
});
} catch (IOException e) {
if (Thread.currentThread().isInterrupted()) {
interrupted = true;
return null;
} else {
logger.log(Level.WARNING, "Could not get document ids for " + query, e);
}
} catch (Exception e) {
logger.log(Level.WARNING, "Could not get document ids for " + query, e);
}
data.documentIds = documentIds;
return data;
}
Aggregations