Trouble with has_parent query containing scripted function_score


(Paul Bellora) #1

I have two document types, in a parent-child relationship:

"myParent" : {
"properties" : {
"weight" : {
"type" : "double"
}
}
}

"myChild" : {
"_parent" : {
"type" : "myParent"
},
"_routing" : {
"required" : true
}
}

The weight field is to be used for custom scoring/sorting. This query
directly against the parent documents works as intended:

{
"query" : {
"function_score" : {
"script_score" : {
"script" : "_score * doc['weight'].value"
}
}
}
}

However, when trying to do similar scoring for the child documents with a
has_parent query, I get an error:

{
"query" : {
"has_parent" : {
"query" : {
"function_score" : {

      "script_score" : {
        "script" : "_score * doc['weight'].value"
      }
    }
  },
  "parent_type" : "myParent",
  "score_type" : "score"
}

}
}

The error is:

QueryPhaseExecutionException[[myIndex][3]:
query[filtered(ParentQuery[myParent](filtered(function score
(ConstantScore(:),function=script[_score * doc['weight'].value], params
[null]))->cache(_type:myParent)))->cache(_type:myChild)],from[0],size[10]:
Query Failed [failed to execute context rewrite]]; nested:
ElasticSearchIllegalArgumentException[No field found for [weight] in
mapping with types [myChild]];

It seems like instead of taking the result of the scoring function and
applying it to the child, ES is taking the scoring function and applying
it to the child, hence the error.

If I don't use score for score_type, the error doesn't occur, although the
results scores are then all 1.0, as documented.

What am I missing here? How can I query these child documents with custom
scoring based on a parent field?

--
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/714f8a04-a88a-4a47-8baf-998992353f1f%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


(Paul Bellora) #2

Update: posted to Stack Overflow with bounty:

On Thursday, January 16, 2014 11:11:27 AM UTC-5, Paul Bellora wrote:

I have two document types, in a parent-child relationship:

"myParent" : {
"properties" : {
"weight" : {
"type" : "double"
}
}
}

"myChild" : {
"_parent" : {
"type" : "myParent"
},
"_routing" : {
"required" : true
}
}

The weight field is to be used for custom scoring/sorting. This query
directly against the parent documents works as intended:

{
"query" : {
"function_score" : {
"script_score" : {
"script" : "_score * doc['weight'].value"
}
}

}
}

However, when trying to do similar scoring for the child documents with a
has_parent query, I get an error:

{
"query" : {
"has_parent" : {
"query" : {
"function_score" : {

      "script_score" : {
        "script" : "_score * doc['weight'].value"
      }
    }
  },
  "parent_type" : "myParent",
  "score_type" : "score"
}

}
}

The error is:

QueryPhaseExecutionException[[myIndex][3]:
query[filtered(ParentQuery[myParent](filtered(function score
(ConstantScore(:),function=script[_score * doc['weight'].value], params
[null]))->cache(_type:myParent)))->cache(_type:myChild)],from[0],size[10]:
Query Failed [failed to execute context rewrite]]; nested:
ElasticSearchIllegalArgumentException[No field found for [weight] in
mapping with types [myChild]];

It seems like instead of taking the result of the scoring function and
applying it to the child, ES is taking the scoring function and
applying it to the child, hence the error.

If I don't use score for score_type, the error doesn't occur, although
the results scores are then all 1.0, as documented.

What am I missing here? How can I query these child documents with custom
scoring based on a parent field?

--
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/a3ec1600-157e-45e9-b006-37cddc2b422f%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


(Martijn Van Groningen) #3

Hi Paul,

The mapping and query that you're sharing make sense and should work. I
verified that with a small recreation:

What I think you're running into is that a document of type 'myParent'
doesn't have the field weight. Can you check if that is the case?
If so you might want to add a null_value for the weight field, so that
all myParent docs have a value for the weight field.

Martijn

On 24 January 2014 21:38, Paul Bellora bellorap@gmail.com wrote:

Update: posted to Stack Overflow with bounty:
http://stackoverflow.com/questions/21289149/trouble-with-has-parent-query-containing-scripted-function-score

On Thursday, January 16, 2014 11:11:27 AM UTC-5, Paul Bellora wrote:

I have two document types, in a parent-child relationship:

"myParent" : {
"properties" : {
"weight" : {
"type" : "double"
}
}
}

"myChild" : {
"_parent" : {
"type" : "myParent"
},
"_routing" : {
"required" : true
}
}

The weight field is to be used for custom scoring/sorting. This query
directly against the parent documents works as intended:

{
"query" : {
"function_score" : {
"script_score" : {
"script" : "_score * doc['weight'].value"
}
}

}
}

However, when trying to do similar scoring for the child documents with a
has_parent query, I get an error:

{
"query" : {
"has_parent" : {
"query" : {
"function_score" : {

      "script_score" : {
        "script" : "_score * doc['weight'].value"
      }
    }
  },
  "parent_type" : "myParent",
  "score_type" : "score"
}

}
}

The error is:

QueryPhaseExecutionException[[myIndex][3]: query[filtered(ParentQuery[myParent](filtered(function
score (ConstantScore(:),function=script[_score * doc['weight'].value],
params [null]))->cache(_type:myParent)))->cache(_type:myChild)],from[0],size[10]:
Query Failed [failed to execute context rewrite]]; nested:
ElasticSearchIllegalArgumentException[No field found for [weight] in
mapping with types [myChild]];

It seems like instead of taking the result of the scoring function and
applying it to the child, ES is taking the scoring function and
applying it to the child, hence the error.

If I don't use score for score_type, the error doesn't occur, although
the results scores are then all 1.0, as documented.

What am I missing here? How can I query these child documents with custom
scoring based on a parent field?

--
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/a3ec1600-157e-45e9-b006-37cddc2b422f%40googlegroups.com
.

For more options, visit https://groups.google.com/groups/opt_out.

--
Met vriendelijke groet,

Martijn van Groningen

--
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/CA%2BA76TwWCtqUb_D17nO4EfgObdiK%2B0GrY9cp69%3D5hy9c0jHgDA%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.


(Paul Bellora) #4

Just to close the loop on this topic, Clinton Gormley posted an answer to
the SO question with a workaround: use doc['*myParent.*weight'].value. He
also opened an issuehttps://github.com/elasticsearch/elasticsearch/issues/4914for this behavior.

Although as I commented on the SO answer, Martin Groningen's gisthttps://gist.github.com/martijnvg/8639841does work fine and I'm not sure what the difference is between the two
cases.

Thank you Martin and Clinton for your help.

On Sunday, January 26, 2014 4:47:48 PM UTC-5, Martijn v Groningen wrote:

Hi Paul,

The mapping and query that you're sharing make sense and should work. I
verified that with a small recreation:
https://gist.github.com/martijnvg/8639841

What I think you're running into is that a document of type 'myParent'
doesn't have the field weight. Can you check if that is the case?
If so you might want to add a null_value for the weight field, so that
all myParent docs have a value for the weight field.

Martijn

On 24 January 2014 21:38, Paul Bellora <bell...@gmail.com <javascript:>>wrote:

Update: posted to Stack Overflow with bounty:
http://stackoverflow.com/questions/21289149/trouble-with-has-parent-query-containing-scripted-function-score

On Thursday, January 16, 2014 11:11:27 AM UTC-5, Paul Bellora wrote:

I have two document types, in a parent-child relationship:

"myParent" : {
"properties" : {
"weight" : {
"type" : "double"
}
}
}

"myChild" : {
"_parent" : {
"type" : "myParent"
},
"_routing" : {
"required" : true
}
}

The weight field is to be used for custom scoring/sorting. This query
directly against the parent documents works as intended:

{
"query" : {
"function_score" : {
"script_score" : {
"script" : "_score * doc['weight'].value"
}
}

}
}

However, when trying to do similar scoring for the child documents with
a has_parent query, I get an error:

{
"query" : {
"has_parent" : {
"query" : {
"function_score" : {

      "script_score" : {
        "script" : "_score * doc['weight'].value"
      }
    }
  },
  "parent_type" : "myParent",
  "score_type" : "score"
}

}
}

The error is:

QueryPhaseExecutionException[[myIndex][3]: query[filtered(ParentQuery[myParent](filtered(function
score (ConstantScore(:),function=script[_score *
doc['weight'].value], params [null]))->cache(_type:
myParent)))->cache(_type:myChild)],from[0],size[10]: Query Failed
[failed to execute context rewrite]]; nested: ElasticSearchIllegalArgumentException[No
field found for [weight] in mapping with types [myChild]];

It seems like instead of taking the result of the scoring function and
applying it to the child, ES is taking the scoring function and
applying it to the child, hence the error.

If I don't use score for score_type, the error doesn't occur, although
the results scores are then all 1.0, as documented.

What am I missing here? How can I query these child documents with
custom scoring based on a parent field?

--
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 elasticsearc...@googlegroups.com <javascript:>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/elasticsearch/a3ec1600-157e-45e9-b006-37cddc2b422f%40googlegroups.com
.

For more options, visit https://groups.google.com/groups/opt_out.

--
Met vriendelijke groet,

Martijn van Groningen

--
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/662aaafb-79fa-4438-857d-43a46aef7c5a%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


(Paul Bellora) #5

If only I'd waited a few minutes. Clinton explains the difference between
my issue and Martin's gist:

The difference is that he didn't specify the type in the URL, so it

searched the mappings for all types for a field called weight. Because
we've specified the type in the URL, it only searched myChild, notmyParent

On Monday, January 27, 2014 3:51:23 PM UTC-5, Paul Bellora wrote:

Just to close the loop on this topic, Clinton Gormley posted an answer to
the SO question with a workaround: use doc['*myParent.*weight'].value. He
also opened an issuehttps://github.com/elasticsearch/elasticsearch/issues/4914for this behavior.

Although as I commented on the SO answer, Martin Groningen's gisthttps://gist.github.com/martijnvg/8639841does work fine and I'm not sure what the difference is between the two
cases.

Thank you Martin and Clinton for your help.

On Sunday, January 26, 2014 4:47:48 PM UTC-5, Martijn v Groningen wrote:

Hi Paul,

The mapping and query that you're sharing make sense and should work. I
verified that with a small recreation:
https://gist.github.com/martijnvg/8639841

What I think you're running into is that a document of type 'myParent'
doesn't have the field weight. Can you check if that is the case?
If so you might want to add a null_value for the weight field, so that
all myParent docs have a value for the weight field.

Martijn

On 24 January 2014 21:38, Paul Bellora bell...@gmail.com wrote:

Update: posted to Stack Overflow with bounty:
http://stackoverflow.com/questions/21289149/trouble-with-has-parent-query-containing-scripted-function-score

On Thursday, January 16, 2014 11:11:27 AM UTC-5, Paul Bellora wrote:

I have two document types, in a parent-child relationship:

"myParent" : {
"properties" : {
"weight" : {
"type" : "double"
}
}
}

"myChild" : {
"_parent" : {
"type" : "myParent"
},
"_routing" : {
"required" : true
}
}

The weight field is to be used for custom scoring/sorting. This query
directly against the parent documents works as intended:

{
"query" : {
"function_score" : {
"script_score" : {
"script" : "_score * doc['weight'].value"
}
}

}
}

However, when trying to do similar scoring for the child documents with
a has_parent query, I get an error:

{
"query" : {
"has_parent" : {
"query" : {
"function_score" : {

      "script_score" : {
        "script" : "_score * doc['weight'].value"
      }
    }
  },
  "parent_type" : "myParent",
  "score_type" : "score"
}

}
}

The error is:

QueryPhaseExecutionException[[myIndex][3]: query[filtered(ParentQuery[myParent](filtered(function
score (ConstantScore(:),function=script[_score *
doc['weight'].value], params [null]))->cache(_type:
myParent)))->cache(_type:myChild)],from[0],size[10]: Query Failed
[failed to execute context rewrite]]; nested: ElasticSearchIllegalArgumentException[No
field found for [weight] in mapping with types [myChild]];

It seems like instead of taking the result of the scoring function and
applying it to the child, ES is taking the scoring function and
applying it to the child, hence the error.

If I don't use score for score_type, the error doesn't occur, although
the results scores are then all 1.0, as documented.

What am I missing here? How can I query these child documents with
custom scoring based on a parent field?

--
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 elasticsearc...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/elasticsearch/a3ec1600-157e-45e9-b006-37cddc2b422f%40googlegroups.com
.

For more options, visit https://groups.google.com/groups/opt_out.

--
Met vriendelijke groet,

Martijn van Groningen

--
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/70ebd4cc-258b-458a-82f1-80b028e0e40f%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


(system) #6