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
}
}
]
}
}
}
}
}
}
}'