Example usage for org.apache.lucene.expressions Expression getSortField

List of usage examples for org.apache.lucene.expressions Expression getSortField

Introduction

In this page you can find the example usage for org.apache.lucene.expressions Expression getSortField.

Prototype

public SortField getSortField(Bindings bindings, boolean reverse) 

Source Link

Document

Get a sort field which can be used to rank documents by this expression.

Usage

From source file:org.apache.solr.schema.WrappedIntPointField.java

License:Apache License

/** static helper for re-use in sibling trie class */
public static SortField getSortField(final SortField superSort, final SchemaField field) {
    field.checkSortability();//from ww w  . j  a  v  a 2  s.  c  o m
    Expression expr = null;
    try {
        expr = JavascriptCompiler.compile(field.getName() + " % 3");
    } catch (Exception e) {
        throw new RuntimeException("impossible?", e);
    }
    SimpleBindings bindings = new SimpleBindings();
    bindings.add(superSort);
    return expr.getSortField(bindings, superSort.getReverse());
}

From source file:org.elasticsearch.script.expression.ExpressionScriptEngineService.java

License:Apache License

@Override
public SearchScript search(CompiledScript compiledScript, SearchLookup lookup,
        @Nullable Map<String, Object> vars) {
    try {//ww w .jav a 2  s.c om
        Expression expr = (Expression) compiledScript.compiled();
        MapperService mapper = lookup.doc().mapperService();
        // NOTE: if we need to do anything complicated with bindings in the future, we can just extend Bindings,
        // instead of complicating SimpleBindings (which should stay simple)
        SimpleBindings bindings = new SimpleBindings();
        ReplaceableConstValueSource specialValue = null;

        for (String variable : expr.variables) {
            if (variable.equals("_score")) {
                bindings.add(new SortField("_score", SortField.Type.SCORE));
            } else if (variable.equals("_value")) {
                specialValue = new ReplaceableConstValueSource();
                bindings.add("_value", specialValue);
                // noop: _value is special for aggregations, and is handled in ExpressionScriptBindings
                // TODO: if some uses it in a scoring expression, they will get a nasty failure when evaluating...need a
                // way to know this is for aggregations and so _value is ok to have...

            } else if (vars != null && vars.containsKey(variable)) {
                // TODO: document and/or error if vars contains _score?
                // NOTE: by checking for the variable in vars first, it allows masking document fields with a global constant,
                // but if we were to reverse it, we could provide a way to supply dynamic defaults for documents missing the field?
                Object value = vars.get(variable);
                if (value instanceof Number) {
                    bindings.add(variable, new DoubleConstValueSource(((Number) value).doubleValue()));
                } else {
                    throw new ScriptException("Parameter [" + variable + "] must be a numeric type");
                }

            } else {
                String fieldname = null;
                String methodname = null;
                VariableContext[] parts = VariableContext.parse(variable);
                if (parts[0].text.equals("doc") == false) {
                    throw new ScriptException("Unknown variable [" + parts[0].text + "] in expression");
                }
                if (parts.length < 2 || parts[1].type != VariableContext.Type.STR_INDEX) {
                    throw new ScriptException(
                            "Variable 'doc' in expression must be used with a specific field like: doc['myfield']");
                } else {
                    fieldname = parts[1].text;
                }
                if (parts.length == 3) {
                    if (parts[2].type == VariableContext.Type.METHOD) {
                        methodname = parts[2].text;
                    } else if (parts[2].type != VariableContext.Type.MEMBER || !"value".equals(parts[2].text)) {
                        throw new ScriptException(
                                "Only the member variable [value] or member methods may be accessed on a field when not accessing the field directly");
                    }
                }
                if (parts.length > 3) {
                    throw new ScriptException("Variable [" + variable
                            + "] does not follow an allowed format of either doc['field'] or doc['field'].method()");
                }

                MappedFieldType fieldType = mapper.smartNameFieldType(fieldname);

                if (fieldType == null) {
                    throw new ScriptException(
                            "Field [" + fieldname + "] used in expression does not exist in mappings");
                }
                if (fieldType.isNumeric() == false) {
                    // TODO: more context (which expression?)
                    throw new ScriptException("Field [" + fieldname + "] used in expression must be numeric");
                }

                IndexFieldData<?> fieldData = lookup.doc().fieldDataService()
                        .getForField((NumberFieldMapper.NumberFieldType) fieldType);
                if (methodname == null) {
                    bindings.add(variable, new FieldDataValueSource(fieldData, MultiValueMode.MIN));
                } else {
                    bindings.add(variable, getMethodValueSource(fieldType, fieldData, fieldname, methodname));
                }
            }
        }

        final boolean needsScores = expr.getSortField(bindings, false).needsScores();
        return new ExpressionSearchScript(compiledScript, bindings, specialValue, needsScores);
    } catch (Exception exception) {
        throw new ScriptException("Error during search with " + compiledScript, exception);
    }
}