elasticsearch 如何在Elasticsearch脚本中访问嵌套数组的文档值?,elasticsearch,groovy,elasticsearch,Groovy" /> elasticsearch 如何在Elasticsearch脚本中访问嵌套数组的文档值?,elasticsearch,groovy,elasticsearch,Groovy" />

elasticsearch 如何在Elasticsearch脚本中访问嵌套数组的文档值?

elasticsearch 如何在Elasticsearch脚本中访问嵌套数组的文档值?,elasticsearch,groovy,elasticsearch,Groovy,给定以下索引,我如何在嵌套数组中选择适当的项并访问它的一个值?这里的目的是在脚本中的值中使用它 # Create mapping curl -XPUT localhost:9200/test/user/_mapping -d ' { "user" : { "properties" : { "name" : { "type" : "string" }, "skills" : { "type": "nested",

给定以下索引,我如何在嵌套数组中选择适当的项并访问它的一个值?这里的目的是在
脚本中的值中使用它

# Create mapping
curl -XPUT localhost:9200/test/user/_mapping -d '
{
  "user" : {
    "properties" : {
      "name" : {
        "type" : "string"
      },
      "skills" : {
        "type": "nested", 
        "properties" : {
          "skill_id" : {
            "type" : "integer"
          },
          "recommendations_count" : {
            "type" : "integer"
          }
        }
      }
    }
  }
}
'

# Indexing Data
curl -XPUT localhost:9200/test/user/1 -d '
{
   "name": "John",
   "skills": [
      {
         "skill_id": 100,
         "recommendations_count": 5
      },
      {
         "skill_id": 200,
         "recommendations_count": 3
      }
   ]
}
'

curl -XPUT localhost:9200/test/user/2 -d '
{
   "name": "Mary",
   "skills": [
      {
         "skill_id": 100,
         "recommendations_count": 9
      },
      {
         "skill_id": 200,
         "recommendations_count": 0
      }
   ]
}
'

我的查询按技能id过滤,效果很好。然后,我希望能够使用
script\u score
来提高
用户
文档的分数,对于给定的技能id,
推荐数越高。
(对于您的特定问题,脚本需要嵌套上下文,就像您对
术语
查询所做的那样

这可以为ES 1.x重写:

curl -XGET 'localhost:9200/test/_search' -d'
{
  "query": {
    "nested": {
      "path": "skills",
      "query": {
        "filtered": {
          "filter": {
            "term": {
              "skills.skill_id": 100
            }
          },
          "query": {
            "function_score": {
              "functions": [
                {
                  "script_score": {
                    "script": "sqrt(1.2 * doc['skills.recommendations_count'].value)"
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}'
对于ES 2.x(过滤器成为ES 2.x中的头等公民,因此语法发生了一些变化以跟上进度!):

注意:我将
term
查询设置为
term
过滤器,因为它对分数没有逻辑影响(无论是否完全匹配)。我还将嵌套字段的名称添加到
term
过滤器中,这是Elasticsearch 2.x和更高版本(以及之前的良好实践)中的要求

这样,您就可以(也应该)尽可能避免使用脚本。这就是其中的一种情况。您还可以选择提供一个“missing”值来控制字段丢失时的情况

这将转换为完全相同的脚本,但它的性能会更好:

curl -XGET 'localhost:9200/test/_search' -d'
{
  "query": {
    "nested": {
      "path": "skills",
      "query": {
        "filtered": {
          "filter": {
            "term": {
              "skills.skill_id": 100
            }
          },
          "query": {
            "function_score": {
              "functions": [
                {
                  "field_value_factor": {
                    "field": "skills.recommendations_count",
                    "factor": 1.2,
                    "modifier": "sqrt",
                    "missing": 0
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}'
对于ES 2.x:

curl -XGET 'localhost:9200/test/_search' -d'
{
  "query": {
    "nested": {
      "path": "skills",
      "query": {
        "bool": {
          "filter": {
            "term": {
              "skills.skill_id": 100
            }
          },
          "must": {
            "function_score": {
              "functions": [
                {
                  "field_value_factor": {
                    "field": "skills.recommendations_count",
                    "factor": 1.2,
                    "modifier": "sqrt",
                    "missing": 0
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}'
脚本速度很慢,而且很复杂。您确实提到了doc值,这是一个很有希望的开始,它建议使用Elasticsearch 2.x,但这可能只是一个术语


如果您刚开始使用Elasticsearch,那么我强烈建议您使用最新版本。

哇,感谢您的回复。底部的过滤器似乎没有根据技能id:100进行过滤。请确保使用
“skills.skill\u id”
而不仅仅是
“skill\u id”
。我是,如果删除内部查询{}使用过滤中的函数进行阻止确实有效。你能用修改后的请求更新你的问题吗?我用ES 1.7.3和ES 2.0.0中的示例数据进行了尝试。你肯定是对的,在第一个版本中忽略了过滤器。我编辑了答案以显示正确的方法。显然不是他
嵌套
逻辑接受
查询
过滤器
,但如果它同时得到这两个!修复以显示正确的方式,它更喜欢
查询
curl -XGET 'localhost:9200/test/_search' -d'
{
  "query": {
    "nested": {
      "path": "skills",
      "query": {
        "filtered": {
          "filter": {
            "term": {
              "skills.skill_id": 100
            }
          },
          "query": {
            "function_score": {
              "functions": [
                {
                  "field_value_factor": {
                    "field": "skills.recommendations_count",
                    "factor": 1.2,
                    "modifier": "sqrt",
                    "missing": 0
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}'
curl -XGET 'localhost:9200/test/_search' -d'
{
  "query": {
    "nested": {
      "path": "skills",
      "query": {
        "bool": {
          "filter": {
            "term": {
              "skills.skill_id": 100
            }
          },
          "must": {
            "function_score": {
              "functions": [
                {
                  "field_value_factor": {
                    "field": "skills.recommendations_count",
                    "factor": 1.2,
                    "modifier": "sqrt",
                    "missing": 0
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}'