我有两种文件类型,处于父子关系中:
"myParent" : {
"properties" : {
"weight" : {
"type" : "double"
}
}
}
"myChild" : {
"_parent" : {
"type" : "myParent"
},
"_routing" : {
"required" : true
}
}
weight
字段用于自定义评分/排序。直接针对父文档的查询按预期工作:
{
"query" : {
"function_score" : {
"script_score" : {
"script" : "_score * doc['weight'].value"
}
}
}
}
但是,当尝试使用has_parent
查询对子文档进行类似评分时,出现错误:
{
"query" : {
"has_parent" : {
"query" : {
"function_score" : {
"script_score" : {
"script" : "_score * doc['weight'].value"
}
}
},
"parent_type" : "myParent",
"score_type" : "score"
}
}
}
错误是:
QueryPhaseExecutionException [[myIndex] [3]:query [filtered(ParentQuery [myParent](过滤后的(功能得分(ConstantScore(:)),function = script [_score * doc ['weight'] .value],params [null])) - > cache(_type:myParent))) - > cache(_type:myChild)],来自[0],size [10]:查询失败[无法执行上下文重写]];嵌套:ElasticSearchIllegalArgumentException [在使用类型[myChild]进行映射时找不到[weight]的字段];
似乎不是将评分函数应用于父级,然后将其结果传递给子级,ES试图将评分函数本身应用于子级,从而导致错误。
如果我不对score
使用score_type
,则不会发生错误,但结果分数全部为1.0
,如文档所述。
我在这里缺少什么?如何根据父字段使用自定义评分查询这些子文档?
答案 0 :(得分:6)
我想说的是一个错误:它使用myChild
映射作为默认上下文,即使您在has_parent
查询中也是如此。但我不确定这个bug有多容易修复。正常。
但是,您可以通过在完整字段名称中包含type
名称来解决此问题:
curl -XGET "http://localhost:9200/t/myChild/_search" -d'
{
"query": {
"has_parent": {
"query": {
"function_score": {
"script_score": {
"script": "_score * doc[\"myParent.weight\"].value"
}
}
},
"parent_type": "myParent",
"score_type": "score"
}
}
}'
我已经打开了一个问题,看看我们是否可以解决此问题#4914
答案 1 :(得分:2)
我认为问题在于您尝试根据child
文档中的字段对parent
个文档进行评分,而功能评分应该反过来。
要解决这个问题,我的想法是将父/子关系和得分与子文档存储在一起。然后,您将过滤子文档并根据子文档中的weight
对其进行评分。
一个例子:
"myParent" : {
"properties" : {
"name" : {
"type" : "string"
}
}
}
"myChild" : {
"_parent" : {
"type" : "myParent"
},
"_routing" : {
"required" : true
},
"properties": {
"weight" : {
"type" : "double"
}
}
}
现在,您可以使用has_parent
过滤器选择具有特定child
的所有parent
个文档,然后使用function score
对其进行评分:
{
"query": {
"filtered": {
"query": {
"function_score" : {
"script_score" : {
"script" : "_score * doc['weight'].value"
}
}
},
"filter": {
"has_parent": {
"parent_type": "myParent",
"query": {
"term": {
"name": "something"
}
}
}
}
}
}
}
因此,如果parent
文档是博客帖子和child
条评论,那么您可以根据weight
过滤所有帖子并对评论进行评分。我怀疑基于childs
得分parents
是可能的,尽管我可能错了:)
免责声明:堆叠溢出的第一篇帖子......