Scripting: Fix expressions to temporarily support filter scripts (#26824)
This commit adds a hack converting 0.0 to false and non-zero to true for expressions operating under a filter context. closes #26429
This commit is contained in:
parent
a6ae6b5a9a
commit
6b53dadcf9
|
@ -38,6 +38,7 @@ import org.elasticsearch.index.mapper.MappedFieldType;
|
|||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.script.ClassPermission;
|
||||
import org.elasticsearch.script.ExecutableScript;
|
||||
import org.elasticsearch.script.FilterScript;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptException;
|
||||
|
@ -107,6 +108,9 @@ public class ExpressionScriptEngine extends AbstractComponent implements ScriptE
|
|||
} else if (context.instanceClazz.equals(ExecutableScript.class)) {
|
||||
ExecutableScript.Factory factory = (p) -> new ExpressionExecutableScript(expr, p);
|
||||
return context.factoryClazz.cast(factory);
|
||||
} else if (context.instanceClazz.equals(FilterScript.class)) {
|
||||
FilterScript.Factory factory = (p, lookup) -> newFilterScript(expr, lookup, p);
|
||||
return context.factoryClazz.cast(factory);
|
||||
}
|
||||
throw new IllegalArgumentException("expression engine does not know how to handle script context [" + context.name + "]");
|
||||
}
|
||||
|
@ -236,6 +240,27 @@ public class ExpressionScriptEngine extends AbstractComponent implements ScriptE
|
|||
return new ExpressionSearchScript(expr, bindings, specialValue, needsScores);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a hack for filter scripts, which must return booleans instead of doubles as expression do.
|
||||
* See https://github.com/elastic/elasticsearch/issues/26429.
|
||||
*/
|
||||
private FilterScript.LeafFactory newFilterScript(Expression expr, SearchLookup lookup, @Nullable Map<String, Object> vars) {
|
||||
SearchScript.LeafFactory searchLeafFactory = newSearchScript(expr, lookup, vars);
|
||||
return ctx -> {
|
||||
SearchScript script = searchLeafFactory.newInstance(ctx);
|
||||
return new FilterScript(vars, lookup, ctx) {
|
||||
@Override
|
||||
public boolean execute() {
|
||||
return script.runAsDouble() != 0.0;
|
||||
}
|
||||
@Override
|
||||
public void setDocument(int docid) {
|
||||
script.setDocument(docid);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* converts a ParseException at compile-time or link-time to a ScriptException
|
||||
*/
|
||||
|
|
|
@ -700,4 +700,19 @@ public class MoreExpressionTests extends ESIntegTestCase {
|
|||
assertEquals(2.0D, rsp.getHits().getAt(1).field("foo").getValue(), 1.0D);
|
||||
assertEquals(2.0D, rsp.getHits().getAt(2).field("foo").getValue(), 1.0D);
|
||||
}
|
||||
|
||||
public void testFilterScript() throws Exception {
|
||||
createIndex("test");
|
||||
ensureGreen("test");
|
||||
indexRandom(true,
|
||||
client().prepareIndex("test", "doc", "1").setSource("foo", 1.0),
|
||||
client().prepareIndex("test", "doc", "2").setSource("foo", 0.0));
|
||||
SearchRequestBuilder builder = buildRequest("doc['foo'].value");
|
||||
Script script = new Script(ScriptType.INLINE, "expression", "doc['foo'].value", Collections.emptyMap());
|
||||
builder.setQuery(QueryBuilders.boolQuery().filter(QueryBuilders.scriptQuery(script)));
|
||||
SearchResponse rsp = builder.get();
|
||||
assertSearchResponse(rsp);
|
||||
assertEquals(1, rsp.getHits().getTotalHits());
|
||||
assertEquals(1.0D, rsp.getHits().getAt(0).field("foo").getValue(), 0.0D);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue