Problem accessing fields from a native script during percolation


(petchemaite) #1
  Hi all,

We're trying to figure out how to access fields from within a native
AbstractSearchScript when it's called from a percolate request that
contains the document to percolate.
We tried to use source mechanism and stored fields to no avail (no errors,
but no matches).
The same scripts are working fine for classic searches.

This was tried with Elasticsearch release 1.1.1 and a snapshot of 2.0.0.

We're running out of ideas, any help would be really appreciated
Thanks!

curl -XPOST http://localhost:9200/index1
curl -XPOST http://localhost:9200/index1/mytype/_mapping -d '{
"properties": {
"source_field": { "type": "string" },
"stored_field": { "type": "string", "stored": true }
}
}'

curl -XPUT "http://localhost:9200/index1/.percolator/1" -d '{
"query": {
"filtered": {
"query" : { "match_all" : {}},
"filter": {
"script": {
"script": "cooccurenceScript",
"params": {
"map": { "list" : [ "a" ] }
},
"lang": "native"
}
}
}
}
}'

curl -XPUT "http://localhost:9200/index1/.percolator/2" -d '{
"query": {
"filtered": {
"query" : { "match_all" : {}},
"filter": {
"script": {
"script": "cooccurenceStoredScript",
"params": {
"map": { "list" : [ "a" ] }
},
"lang": "native"
}
}
}
}
}'

Native scripts:
package test;

import java.util.Map;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.node.Node;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.NativeScriptFactory;

public class CooccurenceScriptFactory extends AbstractComponent implements
NativeScriptFactory{

private final Node node;

@SuppressWarnings("unchecked")
@Inject
public CooccurenceScriptFactory(Node node, Settings settings) {
    super(settings);
    this.node = node;
}

@Override public ExecutableScript newScript (@Nullable 

Map<String,Object> params){
return new CooccurenceScript(node.client(), logger, params);
}
}

package test;

import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.script.AbstractSearchScript;
import org.elasticsearch.search.lookup.SourceLookup;

import java.util.List;
import java.util.Map;

public class CooccurenceScript extends AbstractSearchScript {

private List<String> list = null;

@SuppressWarnings("unchecked")
public CooccurenceScript(Client client, ESLogger logger, @Nullable 

Map<String,Object> params) {
Map<String, Object> map = params == null ? null :
XContentMapValues.nodeMapValue(params.get("map"), null);
if (map == null) {
throw new ElasticsearchIllegalArgumentException("Missing the
map parameter");
}
list = (List) map.get("list");
if (list == null || list.isEmpty()) {
throw new ElasticsearchIllegalArgumentException("Missing the
list parameter or list is empty");
}
}

@Override
public java.lang.Object run() {
    SourceLookup source = source();
    @SuppressWarnings("unchecked")
    List<Object> values = (List<Object>) source.get("source_field");
    if (values == null || values.isEmpty()) {
        return false;
    }
    for (Object localValue : values) {
        boolean result = true;
        for (String s : list) {
            result &= ((String) localValue).contains(s);
        }
        if (result) {
            return true;
        }
    }
    return false;
}

}

package test;

import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.node.Node;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.NativeScriptFactory;

import java.util.Map;

public class CooccurenceStoredScriptFactory extends AbstractComponent
implements NativeScriptFactory{

private final Node node;

@SuppressWarnings("unchecked")
@Inject
public CooccurenceStoredScriptFactory(Node node, Settings settings) {
    super(settings);
    this.node = node;
}

@Override public ExecutableScript newScript (@Nullable 

Map<String,Object> params){
return new CooccurenceStoredScript(node.client(), logger, params);
}
}

package test;

import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.script.AbstractSearchScript;
import org.elasticsearch.search.lookup.FieldLookup;
import org.elasticsearch.search.lookup.FieldsLookup;

import java.util.List;
import java.util.Map;

public class CooccurenceStoredScript extends AbstractSearchScript {

private List<String> list = null;

@SuppressWarnings("unchecked")
public CooccurenceStoredScript(Client client, ESLogger logger, 

@Nullable Map<String,Object> params){
Map<String, Object> map = params == null ? null :
XContentMapValues.nodeMapValue(params.get("map"), null);
if (map == null) {
throw new ElasticsearchIllegalArgumentException("Missing the
map parameter");
}
list = (List) map.get("list");
if (list == null || list.isEmpty()) {
throw new ElasticsearchIllegalArgumentException("Missing the
list parameter or list is empty");
}
}

@Override
public java.lang.Object run() {
    FieldsLookup fields = fields();

    if (fields == null || !fields.containsKey("stored_field")) {
        return false;
    }
    FieldLookup field = ((FieldLookup) fields.get("stored_field"));
    if (field == null) {
        return false;
    }
    List<Object> values = field.getValues();
    if (values == null) {
        return false;
    }
    for (Object localValue : values) {
        boolean result = true;
        for (String s : list) {
            result &= ((String) localValue).contains(s);
        }
        if (result) {
            return true;
        }
    }
    return false;
}

}

--
You received this message because you are subscribed to the Google Groups "elasticsearch" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elasticsearch+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elasticsearch/74601541-b3af-4a07-a4f8-d70a370aadab%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


(system) #2