Using a nested object property within custom_filters_score script

Hi,
An example document in the index is
{
"title": "Red Gucci Dress",
"merchant": "zara",
"price": 1972.34,
"colours": [{"name": "red", "emd": 1.98, "percentage": 45}, {"name": "blue", "emd": 1.99, "percentage": 40}]
}

and i have defined a mapping to let ES know colours is a nested object by posting the following json

{
"nested_product" : {
"properties" : {
"colours" : {
"type" : "nested"
}
}
}
}

I'm facing an issue when i want to use custom_filter_score and in the scoring script I want to use the matched colour's properties to generate the score. Below is the query

{
"query":{
"custom_filters_score" : {
"query": {"match_phrase": {"_all" : "gucci dress"}},
"filters" : [{
"filter" : { "nested" : { "path" : "colours", "filter" : {"term" : {"colours.name" : "blue"}}}},
"script" : "foreach(colour : doc['colours'].values){ if (colour.name == 'blue') {return ((0.1 * colour.percentage * colour.emd));}}"
}
],
"score_mode" : "total"
}
}
}

which throws an error

Query Failed [Failed to execute main query]]; nested: CompileException[[Error: No field found for [colours] in mapping with types [nested_product]]\n[Near : {... foreach(colour : doc['colours' ....}]\n ^\n[Line: 1, Column: 1]]; nested: ElasticSearchIllegalArgumentException[No field found for [colours] in mapping with types [nested_product]]; "

Any help on it would be appreciated

Thanks in Advance,
Veda

Hi Veda,

Colud you try to use _source.colours instead of doc[‘colours’].values?
Maybe, the field in doc means lucene’s field name.
I think that elasticsearch is indexed the nested field as “colours.name”, not object.

Regards,


Jun Ohtani
johtani@gmail.com
blog : http://blog.johtani.info
twitter : http://twitter.com/johtani

2014/01/02 2:49、Veda vedavyas.panneershelvam@gmail.com のメール:

Hi,
An example document in the index is
{
"title": "Red Gucci Dress",
"merchant": "zara",
"price": 1972.34,
"colours": [{"name": "red", "emd": 1.98, "percentage": 45}, {"name":
"blue", "emd": 1.99, "percentage": 40}]
}

and i have defined a mapping to let ES know colours is a nested object by
posting the following json

{
"nested_product" : {
"properties" : {
"colours" : {
"type" : "nested"
}
}
}
}

I'm facing an issue when i want to use custom_filter_score and in the
scoring script I want to use the matched colour's properties to generate the
score. Below is the query

{
"query":{
"custom_filters_score" : {
"query": {"match_phrase": {"_all" : "gucci dress"}},
"filters" : [{
"filter" : { "nested" : { "path" : "colours", "filter" :
{"term" : {"colours.name" : "blue"}}}},
"script" : "foreach(colour : doc['colours'].values){ if
(colour.name == 'blue') {return ((0.1 * colour.percentage * colour.emd));}}"
}
],
"score_mode" : "total"
}
}
}

which throws an error

Query Failed [Failed to execute main query]]; nested:
CompileException[[Error: No field found for [colours] in mapping with types
[nested_product]]\n[Near : {... foreach(colour : doc['colours' ....}]\n
^\n[Line: 1, Column: 1]]; nested: ElasticSearchIllegalArgumentException[No
field found for [colours] in mapping with types [nested_product]]; "

Any help on it would be appreciated

Thanks in Advance,
Veda

--
View this message in context: http://elasticsearch-users.115913.n3.nabble.com/Using-a-nested-object-property-within-custom-filters-score-script-tp4046901.html
Sent from the Elasticsearch Users mailing list archive at Nabble.com.

--
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/1388598575084-4046901.post%40n3.nabble.com.
For more options, visit https://groups.google.com/groups/opt_out.

Hi Veda,

I run into a similar issue like yours.
Have you found a solution to your problem?

Thanks,
Vincent

Here is what I found:

You can't access any fields that is object or nested type through doc[...] notation unfortunately:

... snip.., that the doc[...] notation only allows for simple valued fields (can’t return a json object from it) and makes sense only on non-analyzed or single term based fields.
Reference: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/modules-scripting.html

So, one possible way I found was to access via _source. My data structure was nested array of objects with name and value properties:
"aggs": {
"test": {
"sum": {
"script": "if(_source.containsKey("field_name")){for(e : _source["field_name"]){ ... }};..."

One caveat is that it is very slow compared to accessing via doc...
In my project, it was not a show stopper, but let me know if someone figures out a better way to handle this situation.
Thanks!