CavalliumDBEngine/src/main/java/it/cavallium/dbengine/client/query/QueryParser.java

209 lines
10 KiB
Java
Raw Normal View History

2021-03-02 01:53:36 +01:00
package it.cavallium.dbengine.client.query;
2021-03-02 02:23:34 +01:00
import it.cavallium.dbengine.client.query.current.data.BooleanQueryPart;
import it.cavallium.dbengine.client.query.current.data.BoostQuery;
import it.cavallium.dbengine.client.query.current.data.BoxedQuery;
import it.cavallium.dbengine.client.query.current.data.ConstantScoreQuery;
2022-02-06 19:29:23 +01:00
import it.cavallium.dbengine.client.query.current.data.IntNDPointExactQuery;
import it.cavallium.dbengine.client.query.current.data.IntNDPointRangeQuery;
2021-03-02 02:23:34 +01:00
import it.cavallium.dbengine.client.query.current.data.IntPointExactQuery;
import it.cavallium.dbengine.client.query.current.data.IntPointRangeQuery;
2022-02-06 19:29:23 +01:00
import it.cavallium.dbengine.client.query.current.data.IntPointSetQuery;
import it.cavallium.dbengine.client.query.current.data.LongNDPointExactQuery;
import it.cavallium.dbengine.client.query.current.data.LongNDPointRangeQuery;
2021-03-02 02:23:34 +01:00
import it.cavallium.dbengine.client.query.current.data.LongPointExactQuery;
import it.cavallium.dbengine.client.query.current.data.LongPointRangeQuery;
2022-02-06 19:29:23 +01:00
import it.cavallium.dbengine.client.query.current.data.LongPointSetQuery;
2021-03-02 01:53:36 +01:00
import it.cavallium.dbengine.client.query.current.data.NumericSort;
2021-03-02 02:23:34 +01:00
import it.cavallium.dbengine.client.query.current.data.PhraseQuery;
import it.cavallium.dbengine.client.query.current.data.SortedDocFieldExistsQuery;
import it.cavallium.dbengine.client.query.current.data.SortedNumericDocValuesFieldSlowRangeQuery;
2021-11-16 23:19:23 +01:00
import it.cavallium.dbengine.client.query.current.data.StandardQuery;
2021-03-02 02:23:34 +01:00
import it.cavallium.dbengine.client.query.current.data.SynonymQuery;
import it.cavallium.dbengine.client.query.current.data.TermAndBoost;
import it.cavallium.dbengine.client.query.current.data.TermPosition;
import it.cavallium.dbengine.client.query.current.data.TermQuery;
import it.cavallium.dbengine.client.query.current.data.WildcardQuery;
import it.cavallium.dbengine.lucene.RandomSortField;
2021-11-16 23:19:23 +01:00
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
2021-03-02 02:23:34 +01:00
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.SortedNumericDocValuesField;
2021-03-02 01:53:36 +01:00
import org.apache.lucene.index.Term;
2021-11-16 23:19:23 +01:00
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
import org.apache.lucene.queryparser.flexible.standard.QueryParserUtil;
import org.apache.lucene.queryparser.flexible.standard.StandardQueryParser;
2021-03-02 02:23:34 +01:00
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery.Builder;
import org.apache.lucene.search.DocValuesFieldExistsQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
2021-03-02 01:53:36 +01:00
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortField.Type;
import org.apache.lucene.search.SortedNumericSortField;
public class QueryParser {
2021-11-16 23:19:23 +01:00
public static Query toQuery(it.cavallium.dbengine.client.query.current.data.Query query, Analyzer analyzer) {
2021-03-02 01:53:36 +01:00
if (query == null) return null;
2021-03-02 02:23:34 +01:00
switch (query.getBasicType$()) {
2021-11-16 23:19:23 +01:00
case StandardQuery:
var standardQuery = (it.cavallium.dbengine.client.query.current.data.StandardQuery) query;
var standardQueryParser = new StandardQueryParser(analyzer);
var defaultFields = standardQuery.defaultFields();
try {
if (defaultFields.size() > 1) {
standardQueryParser.setMultiFields(defaultFields.toArray(String[]::new));
return standardQueryParser.parse(standardQuery.query(), null);
} else if (defaultFields.size() == 1) {
return standardQueryParser.parse(standardQuery.query(), defaultFields.get(0));
} else {
throw new IllegalStateException("Can't parse a standard query expression that has 0 default fields");
}
} catch (QueryNodeException e) {
throw new IllegalStateException("Can't parse query expression \"" + standardQuery.query() + "\"", e);
}
2021-03-02 02:23:34 +01:00
case BooleanQuery:
var booleanQuery = (it.cavallium.dbengine.client.query.current.data.BooleanQuery) query;
var bq = new Builder();
2021-07-13 18:07:19 +02:00
for (BooleanQueryPart part : booleanQuery.parts()) {
Occur occur = switch (part.occur().getBasicType$()) {
case OccurFilter -> Occur.FILTER;
case OccurMust -> Occur.MUST;
case OccurShould -> Occur.SHOULD;
case OccurMustNot -> Occur.MUST_NOT;
default -> throw new IllegalStateException("Unexpected value: " + part.occur().getBasicType$());
};
2021-11-16 23:19:23 +01:00
bq.add(toQuery(part.query(), analyzer), occur);
2021-03-02 02:23:34 +01:00
}
2021-07-13 18:07:19 +02:00
bq.setMinimumNumberShouldMatch(booleanQuery.minShouldMatch());
2021-03-02 02:23:34 +01:00
return bq.build();
case IntPointExactQuery:
var intPointExactQuery = (IntPointExactQuery) query;
2021-07-13 18:07:19 +02:00
return IntPoint.newExactQuery(intPointExactQuery.field(), intPointExactQuery.value());
2022-02-06 19:29:23 +01:00
case IntNDPointExactQuery:
var intndPointExactQuery = (IntNDPointExactQuery) query;
var intndValues = intndPointExactQuery.value().toIntArray();
return IntPoint.newRangeQuery(intndPointExactQuery.field(), intndValues, intndValues);
2021-03-02 02:23:34 +01:00
case LongPointExactQuery:
var longPointExactQuery = (LongPointExactQuery) query;
2021-07-13 18:07:19 +02:00
return LongPoint.newExactQuery(longPointExactQuery.field(), longPointExactQuery.value());
2022-02-06 19:29:23 +01:00
case LongNDPointExactQuery:
var longndPointExactQuery = (LongNDPointExactQuery) query;
var longndValues = longndPointExactQuery.value().toLongArray();
return LongPoint.newRangeQuery(longndPointExactQuery.field(), longndValues, longndValues);
case IntPointSetQuery:
var intPointSetQuery = (IntPointSetQuery) query;
return IntPoint.newSetQuery(intPointSetQuery.field(), intPointSetQuery.values().toIntArray());
case LongPointSetQuery:
var longPointSetQuery = (LongPointSetQuery) query;
return LongPoint.newSetQuery(longPointSetQuery.field(), longPointSetQuery.values().toLongArray());
2021-03-02 02:23:34 +01:00
case TermQuery:
var termQuery = (TermQuery) query;
2021-07-13 18:07:19 +02:00
return new org.apache.lucene.search.TermQuery(toTerm(termQuery.term()));
2021-03-02 02:23:34 +01:00
case BoostQuery:
var boostQuery = (BoostQuery) query;
2021-11-16 23:19:23 +01:00
return new org.apache.lucene.search.BoostQuery(toQuery(boostQuery.query(), analyzer), boostQuery.scoreBoost());
2021-03-02 02:23:34 +01:00
case ConstantScoreQuery:
var constantScoreQuery = (ConstantScoreQuery) query;
2021-11-16 23:19:23 +01:00
return new org.apache.lucene.search.ConstantScoreQuery(toQuery(constantScoreQuery.query(), analyzer));
2021-03-02 02:23:34 +01:00
case BoxedQuery:
2021-11-16 23:19:23 +01:00
return toQuery(((BoxedQuery) query).query(), analyzer);
2021-03-02 02:23:34 +01:00
case FuzzyQuery:
var fuzzyQuery = (it.cavallium.dbengine.client.query.current.data.FuzzyQuery) query;
2021-07-13 18:07:19 +02:00
return new FuzzyQuery(toTerm(fuzzyQuery.term()),
fuzzyQuery.maxEdits(),
fuzzyQuery.prefixLength(),
fuzzyQuery.maxExpansions(),
fuzzyQuery.transpositions()
2021-03-02 02:23:34 +01:00
);
case IntPointRangeQuery:
var intPointRangeQuery = (IntPointRangeQuery) query;
2021-07-13 18:07:19 +02:00
return IntPoint.newRangeQuery(intPointRangeQuery.field(),
intPointRangeQuery.min(),
intPointRangeQuery.max()
2021-03-02 02:23:34 +01:00
);
2022-02-06 19:29:23 +01:00
case IntNDPointRangeQuery:
var intndPointRangeQuery = (IntNDPointRangeQuery) query;
return IntPoint.newRangeQuery(intndPointRangeQuery.field(),
intndPointRangeQuery.min().toIntArray(),
intndPointRangeQuery.max().toIntArray()
);
2021-03-02 02:23:34 +01:00
case LongPointRangeQuery:
var longPointRangeQuery = (LongPointRangeQuery) query;
2021-07-13 18:07:19 +02:00
return LongPoint.newRangeQuery(longPointRangeQuery.field(),
longPointRangeQuery.min(),
longPointRangeQuery.max()
2021-03-02 02:23:34 +01:00
);
2022-02-06 19:29:23 +01:00
case LongNDPointRangeQuery:
var longndPointRangeQuery = (LongNDPointRangeQuery) query;
return LongPoint.newRangeQuery(longndPointRangeQuery.field(),
longndPointRangeQuery.min().toLongArray(),
longndPointRangeQuery.max().toLongArray()
);
2021-03-02 02:23:34 +01:00
case MatchAllDocsQuery:
return new MatchAllDocsQuery();
case MatchNoDocsQuery:
return new MatchNoDocsQuery();
case PhraseQuery:
var phraseQuery = (PhraseQuery) query;
var pqb = new org.apache.lucene.search.PhraseQuery.Builder();
2021-07-13 18:07:19 +02:00
for (TermPosition phrase : phraseQuery.phrase()) {
pqb.add(toTerm(phrase.term()), phrase.position());
2021-03-02 02:23:34 +01:00
}
2021-07-13 18:07:19 +02:00
pqb.setSlop(phraseQuery.slop());
2021-03-02 02:23:34 +01:00
return pqb.build();
case SortedDocFieldExistsQuery:
var sortedDocFieldExistsQuery = (SortedDocFieldExistsQuery) query;
2021-07-13 18:07:19 +02:00
return new DocValuesFieldExistsQuery(sortedDocFieldExistsQuery.field());
2021-03-02 02:23:34 +01:00
case SynonymQuery:
var synonymQuery = (SynonymQuery) query;
2021-07-13 18:07:19 +02:00
var sqb = new org.apache.lucene.search.SynonymQuery.Builder(synonymQuery.field());
for (TermAndBoost part : synonymQuery.parts()) {
sqb.addTerm(toTerm(part.term()), part.boost());
2021-03-02 02:23:34 +01:00
}
return sqb.build();
case SortedNumericDocValuesFieldSlowRangeQuery:
var sortedNumericDocValuesFieldSlowRangeQuery = (SortedNumericDocValuesFieldSlowRangeQuery) query;
2021-07-13 18:07:19 +02:00
return SortedNumericDocValuesField.newSlowRangeQuery(sortedNumericDocValuesFieldSlowRangeQuery.field(),
sortedNumericDocValuesFieldSlowRangeQuery.min(),
sortedNumericDocValuesFieldSlowRangeQuery.max()
2021-03-02 02:23:34 +01:00
);
case WildcardQuery:
var wildcardQuery = (WildcardQuery) query;
2021-07-13 18:07:19 +02:00
return new org.apache.lucene.search.WildcardQuery(new Term(wildcardQuery.field(), wildcardQuery.pattern()));
2021-03-02 02:23:34 +01:00
default:
throw new IllegalStateException("Unexpected value: " + query.getBasicType$());
}
}
private static Term toTerm(it.cavallium.dbengine.client.query.current.data.Term term) {
2021-07-13 18:07:19 +02:00
return new Term(term.field(), term.value());
2021-03-02 01:53:36 +01:00
}
public static Sort toSort(it.cavallium.dbengine.client.query.current.data.Sort sort) {
switch (sort.getBasicType$()) {
case NoSort:
return null;
case ScoreSort:
return new Sort(SortField.FIELD_SCORE);
case DocSort:
return new Sort(SortField.FIELD_DOC);
case NumericSort:
NumericSort numericSort = (NumericSort) sort;
2021-07-13 18:07:19 +02:00
return new Sort(new SortedNumericSortField(numericSort.field(), Type.LONG, numericSort.reverse()));
case RandomSort:
return new Sort(new RandomSortField());
2021-03-02 01:53:36 +01:00
default:
throw new IllegalStateException("Unexpected value: " + sort.getBasicType$());
}
}
public static it.cavallium.dbengine.client.query.current.data.Term toQueryTerm(Term term) {
return it.cavallium.dbengine.client.query.current.data.Term.of(term.field(), term.text());
}
}