如何在Elasticsearch脚本中访问嵌套数组的doc值?
给定以下索引,我如何在嵌套数组中选择适当的项目并访问其中的一个值?目的是在内的值中使用它script_score
。
# Create mappingcurl -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
}
]
}
'
我的查询按skill_id过滤,效果很好。然后,我希望能够
使用更高script_score
的分数来提高user
文档的分数recommendations_count
(<-这是关键)。
curl -XPOST localhost:9200/test/user/_search -d '{
"query":{
"function_score":{
"query":{
"bool":{
"must":{
"nested":{
"path":"skills",
"query":{
"bool":{
"must":{
"term":{
"skill_id":100
}
}
}
}
}
}
}
},
"functions":[
{
"script_score": {
"script": "sqrt(1.2 * doc['skills.recommendations_count'].value)"
}
}
]
}
}
}
}
'
如何skills
从中访问数组,在数组中script
找到’skill_id:100’项目,然后使用其recommendations_count
值?在script_score
上述目前不工作(比分始终是0,而不管数据的,所以我想doc['skills.recommendations_count'].value
在正确的地方是不看。
回答:
对于您的特定问题,脚本需要嵌套上下文,就像您对term
查询所做的一样。
可以为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中成为一等公民,因此语法进行了一些更改以跟上!):
curl -XGET 'localhost:9200/test/_search' -d'{
"query": {
"nested": {
"path": "skills",
"query": {
"bool": {
"filter": {
"term": {
"skills.skill_id": 100
}
},
"must": {
"function_score": {
"functions": [
{
"script_score": {
"script": "sqrt(1.2 * doc['skills.recommendations_count'].value)"
}
}
]
}
}
}
}
}
}
}'
注意:我使term
查询成为term
过滤器,因为它对分数没有逻辑影响(无论是完全匹配还是不完全匹配)。我还将嵌套字段的名称添加到了term
过滤器中,这是Elasticsearch
2.x和更高版本(以及先前的良好实践)的要求。
这样一来,您就可以( 并且
应该)避免尽可能使用脚本。这是其中一种情况。function_score
支持field_value_factor
功能的概念,该功能使您可以完全按照自己的尝试去做,但完全不需要脚本。您还可以选择提供一个“
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
}
}
]
}
}
}
}
}
}
}'
脚本很慢,并且 也 暗示着Elasticsearch
1.x中使用fielddata,这很糟糕。您确实提到了doc值,这是一个有希望的开端,它表明使用Elasticsearch 2.x,但这可能只是术语。
如果您只是从Elasticsearch开始,那么我强烈建议从最新版本开始。
以上是 如何在Elasticsearch脚本中访问嵌套数组的doc值? 的全部内容, 来源链接: utcz.com/qa/406026.html