in solr/core/src/java/org/apache/solr/search/ValueSourceParser.java [158:1359]
static {
addParser(
"testfunc",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
final ValueSource source = fp.parseValueSource();
return new TestValueSource(source);
}
});
addParser(
"ord",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
String field = fp.parseId();
return new OrdFieldSource(field);
}
});
addParser(
"literal",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new LiteralValueSource(fp.parseArg());
}
});
addParser(
"threadid",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new LongConstValueSource(Thread.currentThread().threadId());
}
});
addParser(
"sleep",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
int ms = fp.parseInt();
ValueSource source = fp.parseValueSource();
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return source;
}
});
addParser(
"rord",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
String field = fp.parseId();
return new ReverseOrdFieldSource(field);
}
});
addParser(
"top",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
// top(vs) is now a no-op
ValueSource source = fp.parseValueSource();
return source;
}
});
addParser(
"linear",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource source = fp.parseValueSource();
float slope = fp.parseFloat();
float intercept = fp.parseFloat();
return new LinearFloatFunction(source, slope, intercept);
}
});
addParser(
"recip",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource source = fp.parseValueSource();
float m = fp.parseFloat();
float a = fp.parseFloat();
float b = fp.parseFloat();
return new ReciprocalFloatFunction(source, m, a, b);
}
});
addParser(
"scale",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource source = fp.parseValueSource();
float min = fp.parseFloat();
float max = fp.parseFloat();
return new ScaleFloatFunction(source, min, max);
}
});
addParser(
"div",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource a = fp.parseValueSource();
ValueSource b = fp.parseValueSource();
return new DivFloatFunction(a, b);
}
});
addParser(
"mod",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource a = fp.parseValueSource();
ValueSource b = fp.parseValueSource();
return new DualDoubleFunction(a, b) {
@Override
protected String name() {
return "mod";
}
@Override
protected double func(int doc, FunctionValues aVals, FunctionValues bVals)
throws IOException {
return aVals.doubleVal(doc) % bVals.doubleVal(doc);
}
};
}
});
addParser(
"map",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource source = fp.parseValueSource();
float min = fp.parseFloat();
float max = fp.parseFloat();
ValueSource target = fp.parseValueSource();
ValueSource def = fp.hasMoreArguments() ? fp.parseValueSource() : null;
return new RangeMapFloatFunction(source, min, max, target, def);
}
});
addParser(
"abs",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource source = fp.parseValueSource();
return new SimpleFloatFunction(source) {
@Override
protected String name() {
return "abs";
}
@Override
protected float func(int doc, FunctionValues vals) throws IOException {
return Math.abs(vals.floatVal(doc));
}
};
}
});
addParser(
"cscore",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new CollapseScoreFunction();
}
});
addParser(
"sum",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
return new SumFloatFunction(sources.toArray(new ValueSource[0]));
}
});
alias("sum", "add");
addParser("vectorSimilarity", new VectorSimilaritySourceParser());
addParser(
"product",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
return new ProductFloatFunction(sources.toArray(new ValueSource[0]));
}
});
alias("product", "mul");
addParser(
"sub",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource a = fp.parseValueSource();
ValueSource b = fp.parseValueSource();
return new DualFloatFunction(a, b) {
@Override
protected String name() {
return "sub";
}
@Override
protected float func(int doc, FunctionValues aVals, FunctionValues bVals)
throws IOException {
return aVals.floatVal(doc) - bVals.floatVal(doc);
}
};
}
});
addParser(
"vector",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new VectorValueSource(fp.parseValueSourceList());
}
});
addParser(
"query",
new ValueSourceParser() {
// boost(query($q),rating)
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
Query q = fp.parseNestedQuery();
float defVal = 0.0f;
if (fp.hasMoreArguments()) {
defVal = fp.parseFloat();
}
return new QueryValueSource(q, defVal);
}
});
addParser(
"boost",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
Query q = fp.parseNestedQuery();
ValueSource vs = fp.parseValueSource();
return new QueryValueSource(
FunctionScoreQuery.boostByValue(q, vs.asDoubleValuesSource()), 0.0f);
}
});
addParser(
"joindf",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
String f0 = fp.parseArg();
String qf = fp.parseArg();
return new JoinDocFreqValueSource(f0, qf);
}
});
addParser("geodist", new GeoDistValueSourceParser());
addParser(
"hsin",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
double radius = fp.parseDouble();
// SOLR-2114, make the convert flag required, since the parser doesn't support much in
// the way of lookahead or the ability to convert a String into a ValueSource
boolean convert = Boolean.parseBoolean(fp.parseArg());
MultiValueSource pv1;
MultiValueSource pv2;
ValueSource one = fp.parseValueSource();
ValueSource two = fp.parseValueSource();
if (fp.hasMoreArguments()) {
pv1 = new VectorValueSource(Arrays.asList(one, two)); // x1, y1
pv2 =
new VectorValueSource(
Arrays.asList(fp.parseValueSource(), fp.parseValueSource())); // x2, y2
} else {
// check to see if we have multiValue source
if (one instanceof MultiValueSource && two instanceof MultiValueSource) {
pv1 = (MultiValueSource) one;
pv2 = (MultiValueSource) two;
} else {
throw new SolrException(
SolrException.ErrorCode.BAD_REQUEST,
"Input must either be 2 MultiValueSources, or there must be 4 ValueSources");
}
}
return new HaversineFunction(pv1, pv2, radius, convert);
}
});
addParser(
"ghhsin",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
double radius = fp.parseDouble();
ValueSource gh1 = fp.parseValueSource();
ValueSource gh2 = fp.parseValueSource();
return new GeohashHaversineFunction(gh1, gh2, radius);
}
});
addParser(
"geohash",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource lat = fp.parseValueSource();
ValueSource lon = fp.parseValueSource();
return new GeohashFunction(lat, lon);
}
});
addParser(
"strdist",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource str1 = fp.parseValueSource();
ValueSource str2 = fp.parseValueSource();
String distClass = fp.parseArg();
StringDistance dist = null;
if (distClass.equalsIgnoreCase("jw")) {
dist = new JaroWinklerDistance();
} else if (distClass.equalsIgnoreCase("edit")) {
dist = new LevenshteinDistance();
} else if (distClass.equalsIgnoreCase("ngram")) {
int ngram = 2;
if (fp.hasMoreArguments()) {
ngram = fp.parseInt();
}
dist = new NGramDistance(ngram);
} else {
dist =
fp.req.getCore().getResourceLoader().newInstance(distClass, StringDistance.class);
}
return new StringDistanceFunction(str1, str2, dist);
}
});
addParser(
"field",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
String fieldName = fp.parseArg();
SchemaField f = fp.getReq().getSchema().getField(fieldName);
if (fp.hasMoreArguments()) {
// multivalued selector option
String s = fp.parseArg();
FieldType.MultiValueSelector selector = FieldType.MultiValueSelector.lookup(s);
if (null == selector) {
throw new SolrException(
SolrException.ErrorCode.BAD_REQUEST,
"Multi-Valued field selector '" + s + "' not supported");
}
return f.getType().getSingleValueSource(selector, f, fp);
}
// simple field ValueSource
return f.getType().getValueSource(f, fp);
}
});
addParser(
"currency",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
String fieldName = fp.parseArg();
SchemaField f = fp.getReq().getSchema().getField(fieldName);
if (!(f.getType() instanceof CurrencyFieldType ft)) {
throw new SolrException(
SolrException.ErrorCode.BAD_REQUEST,
"Currency function input must be the name of a CurrencyFieldType: " + fieldName);
}
String code = fp.hasMoreArguments() ? fp.parseArg() : null;
return ft.getConvertedValueSource(code, ft.getValueSource(f, fp));
}
});
addParser(
new DoubleParser("rad") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return vals.doubleVal(doc) * DistanceUtils.DEGREES_TO_RADIANS;
}
});
addParser(
new DoubleParser("deg") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return vals.doubleVal(doc) * DistanceUtils.RADIANS_TO_DEGREES;
}
});
addParser(
new DoubleParser("sqrt") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.sqrt(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("cbrt") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.cbrt(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("log") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.log10(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("ln") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.log(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("exp") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.exp(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("sin") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.sin(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("cos") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.cos(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("tan") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.tan(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("asin") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.asin(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("acos") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.acos(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("atan") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.atan(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("sinh") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.sinh(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("cosh") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.cosh(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("tanh") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.tanh(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("ceil") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.ceil(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("floor") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.floor(vals.doubleVal(doc));
}
});
addParser(
new DoubleParser("rint") {
@Override
public double func(int doc, FunctionValues vals) throws IOException {
return Math.rint(vals.doubleVal(doc));
}
});
addParser(
new Double2Parser("pow") {
@Override
public double func(int doc, FunctionValues a, FunctionValues b) throws IOException {
return Math.pow(a.doubleVal(doc), b.doubleVal(doc));
}
});
addParser(
new Double2Parser("hypot") {
@Override
public double func(int doc, FunctionValues a, FunctionValues b) throws IOException {
return Math.hypot(a.doubleVal(doc), b.doubleVal(doc));
}
});
addParser(
new Double2Parser("atan2") {
@Override
public double func(int doc, FunctionValues a, FunctionValues b) throws IOException {
return Math.atan2(a.doubleVal(doc), b.doubleVal(doc));
}
});
addParser(
"max",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
return new MaxFloatFunction(sources.toArray(new ValueSource[0]));
}
});
addParser(
"min",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
return new MinFloatFunction(sources.toArray(new ValueSource[0]));
}
});
addParser(
"sqedist",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
MVResult mvr = getMultiValueSources(sources);
return new SquaredEuclideanFunction(mvr.mv1, mvr.mv2);
}
});
addParser(
"dist",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
float power = fp.parseFloat();
List<ValueSource> sources = fp.parseValueSourceList();
MVResult mvr = getMultiValueSources(sources);
return new VectorDistanceFunction(power, mvr.mv1, mvr.mv2);
}
});
addParser("ms", new DateValueSourceParser());
addParser(
"pi",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) {
return new DoubleConstValueSource(Math.PI);
}
});
addParser(
"e",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) {
return new DoubleConstValueSource(Math.E);
}
});
addParser(
"docfreq",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
TInfo tinfo = parseTerm(fp);
return new DocFreqValueSource(
tinfo.field, tinfo.val, tinfo.indexedField, tinfo.indexedBytes.get());
}
});
addParser(
"totaltermfreq",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
TInfo tinfo = parseTerm(fp);
return new TotalTermFreqValueSource(
tinfo.field, tinfo.val, tinfo.indexedField, tinfo.indexedBytes.get());
}
});
alias("totaltermfreq", "ttf");
addParser(
"sumtotaltermfreq",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
String field = fp.parseArg();
return new SumTotalTermFreqValueSource(field);
}
});
alias("sumtotaltermfreq", "sttf");
addParser(
"idf",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
TInfo tinfo = parseTerm(fp);
return new IDFValueSource(
tinfo.field, tinfo.val, tinfo.indexedField, tinfo.indexedBytes.get());
}
});
addParser(
"termfreq",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
TInfo tinfo = parseTerm(fp);
return new TermFreqValueSource(
tinfo.field, tinfo.val, tinfo.indexedField, tinfo.indexedBytes.get());
}
});
addParser(
"tf",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
TInfo tinfo = parseTerm(fp);
return new TFValueSource(
tinfo.field, tinfo.val, tinfo.indexedField, tinfo.indexedBytes.get());
}
});
addParser(
"norm",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
String field = fp.parseArg();
return new NormValueSource(field);
}
});
addParser(
"maxdoc",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) {
return new MaxDocValueSource();
}
});
addParser(
"numdocs",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) {
return new NumDocsValueSource();
}
});
addParser(
"payload",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
// payload(field,value[,default, ['min|max|average|first']])
// defaults to "average" and 0.0 default value
// would have made this parser a new separate class and registered it, but
// this handy method is private :/
TInfo tinfo = parseTerm(fp);
ValueSource defaultValueSource;
if (fp.hasMoreArguments()) {
defaultValueSource = fp.parseValueSource();
} else {
defaultValueSource = new ConstValueSource(0.0f);
}
PayloadFunction payloadFunction = null;
String func = "average";
if (fp.hasMoreArguments()) {
func = fp.parseArg();
}
payloadFunction = PayloadUtils.getPayloadFunction(func);
// Support func="first" by payloadFunction=null
if (payloadFunction == null && !"first".equals(func)) {
// not "first" (or average, min, or max)
throw new SolrException(
SolrException.ErrorCode.BAD_REQUEST, "Invalid payload function: " + func);
}
IndexSchema schema = fp.getReq().getCore().getLatestSchema();
PayloadDecoder decoder = schema.getPayloadDecoder(tinfo.field);
if (decoder == null) {
throw new SolrException(
SolrException.ErrorCode.BAD_REQUEST,
"No payload decoder found for field: " + tinfo.field);
}
return new FloatPayloadValueSource(
tinfo.field,
tinfo.val,
tinfo.indexedField,
tinfo.indexedBytes.get(),
decoder,
payloadFunction,
defaultValueSource);
}
});
addParser(
"true",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) {
return BoolConstValueSource.TRUE;
}
});
addParser(
"false",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) {
return BoolConstValueSource.FALSE;
}
});
addParser(
"exists",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource vs = fp.parseValueSource();
return new SimpleBoolFunction(vs) {
@Override
protected String name() {
return "exists";
}
@Override
protected boolean func(int doc, FunctionValues vals) throws IOException {
return vals.exists(doc);
}
};
}
});
addParser(
"isnan",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource vs = fp.parseValueSource();
return new SimpleBoolFunction(vs) {
@Override
protected String name() {
return "isnan";
}
@Override
protected boolean func(int doc, FunctionValues vals) throws IOException {
return Float.isNaN(vals.floatVal(doc));
}
};
}
});
addParser(
"not",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource vs = fp.parseValueSource();
return new SimpleBoolFunction(vs) {
@Override
protected boolean func(int doc, FunctionValues vals) throws IOException {
return !vals.boolVal(doc);
}
@Override
protected String name() {
return "not";
}
};
}
});
addParser(
"and",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
return new MultiBoolFunction(sources) {
@Override
protected String name() {
return "and";
}
@Override
protected boolean func(int doc, FunctionValues[] vals) throws IOException {
for (FunctionValues dv : vals) if (!dv.boolVal(doc)) return false;
return true;
}
};
}
});
addParser(
"or",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
return new MultiBoolFunction(sources) {
@Override
protected String name() {
return "or";
}
@Override
protected boolean func(int doc, FunctionValues[] vals) throws IOException {
for (FunctionValues dv : vals) if (dv.boolVal(doc)) return true;
return false;
}
};
}
});
addParser(
"xor",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
return new MultiBoolFunction(sources) {
@Override
protected String name() {
return "xor";
}
@Override
protected boolean func(int doc, FunctionValues[] vals) throws IOException {
int nTrue = 0, nFalse = 0;
for (FunctionValues dv : vals) {
if (dv.boolVal(doc)) nTrue++;
else nFalse++;
}
return nTrue != 0 && nFalse != 0;
}
};
}
});
addParser(
"if",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource ifValueSource = fp.parseValueSource();
ValueSource trueValueSource = fp.parseValueSource();
ValueSource falseValueSource = fp.parseValueSource();
return new IfFunction(ifValueSource, trueValueSource, falseValueSource);
}
});
addParser(
"gt",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource lhsValSource = fp.parseValueSource();
ValueSource rhsValSource = fp.parseValueSource();
return new SolrComparisonBoolFunction(
lhsValSource, rhsValSource, "gt", (cmp) -> cmp > 0);
}
});
addParser(
"lt",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource lhsValSource = fp.parseValueSource();
ValueSource rhsValSource = fp.parseValueSource();
return new SolrComparisonBoolFunction(
lhsValSource, rhsValSource, "lt", (cmp) -> cmp < 0);
}
});
addParser(
"gte",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource lhsValSource = fp.parseValueSource();
ValueSource rhsValSource = fp.parseValueSource();
return new SolrComparisonBoolFunction(
lhsValSource, rhsValSource, "gte", (cmp) -> cmp >= 0);
}
});
addParser(
"lte",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource lhsValSource = fp.parseValueSource();
ValueSource rhsValSource = fp.parseValueSource();
return new SolrComparisonBoolFunction(
lhsValSource, rhsValSource, "lte", (cmp) -> cmp <= 0);
}
});
addParser(
"eq",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
ValueSource lhsValSource = fp.parseValueSource();
ValueSource rhsValSource = fp.parseValueSource();
return new EqualFunction(lhsValSource, rhsValSource, "eq");
}
});
addParser(
"def",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new DefFunction(fp.parseValueSourceList());
}
});
addParser(
"concat",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<ValueSource> sources = fp.parseValueSourceList();
return new ConcatStringFunction(sources.toArray(new ValueSource[0]));
}
});
addParser(
"agg",
new ValueSourceParser() {
@Override
public AggValueSource parse(FunctionQParser fp) throws SyntaxError {
return fp.parseAgg(FunctionQParser.FLAG_DEFAULT);
}
});
addParser(
"agg_count",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new CountAgg();
}
});
addParser(
"agg_unique",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new UniqueAgg(fp.parseArg());
}
});
addParser(
"agg_uniqueBlock",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
if (fp.sp.peek() == QueryParsing.LOCALPARAM_START.charAt(0)) {
return new UniqueBlockQueryAgg(fp.parseNestedQuery());
}
return new UniqueBlockFieldAgg(fp.parseArg());
}
});
addParser(
"agg_hll",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new HLLAgg(fp.parseArg());
}
});
addParser(
"agg_sum",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new SumAgg(
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
addParser(
"agg_avg",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new AvgAgg(
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
addParser(
"agg_sumsq",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new SumsqAgg(
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
addParser(
"agg_variance",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new VarianceAgg(
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
addParser(
"agg_stddev",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new StddevAgg(
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
addParser(
"agg_missing",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new MissingAgg(
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
addParser(
"agg_countvals",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new CountValsAgg(
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
/*
addParser("agg_multistat", new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return null;
}
});
*/
addParser(
"agg_min",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new MinMaxAgg(
"min",
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
addParser(
"agg_max",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
return new MinMaxAgg(
"max",
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE));
}
});
addParser(
"agg_percentile",
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
List<Double> percentiles = new ArrayList<>();
ValueSource vs =
fp.parseValueSource(
FunctionQParser.FLAG_DEFAULT | FunctionQParser.FLAG_USE_FIELDNAME_SOURCE);
while (fp.hasMoreArguments()) {
double val = fp.parseDouble();
if (val < 0 || val > 100) {
throw new SyntaxError(
"requested percentile must be between 0 and 100. got " + val);
}
percentiles.add(val);
}
if (percentiles.isEmpty()) {
throw new SyntaxError(
"expected percentile(valsource,percent1[,percent2]*) EXAMPLE:percentile(myfield,50)");
}
return new PercentileAgg(vs, percentiles);
}
});
addParser(
"agg_" + RelatednessAgg.NAME,
new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
// TODO: (fore & back)-ground should be optional -- use hasMoreArguments
// if only one arg, assume it's the foreground
// (background is the one that will most commonly just be "*:*")
// see notes in RelatednessAgg constructor about why we don't do this yet
RelatednessAgg agg = new RelatednessAgg(fp.parseNestedQuery(), fp.parseNestedQuery());
agg.setOpts(fp);
return agg;
}
});
addParser("childfield", new ChildFieldValueSourceParser());
}