当前位置: 首页 > 知识库问答 >
问题:

ElasticSearch通过自定义参数筛选无痛脚本

戚奇略
2023-03-14

我试图创建一个简单的脚本,通过自定义参数数组过滤嵌套字段数组,通过我的for循环抛出错误。

映射

    {
        "documents": {
            "mappings": {
                "document": {
                    "properties": {
                        "properties": {
                            "type": "nested",
                            "properties": {
                                "key": {
                                    "type": "text",
                                    "fields": {
                                        "keyword": {
                                            "type": "keyword",
                                            "ignore_above": 256
                                        }
                                    }
                                },
                                "value": {
                                    "type": "text",
                                    "fields": {
                                        "keyword": {
                                            "type": "keyword",
                                            "ignore_above": 256
                                        }
                                    }
                                }
                            }
                        },
                        "performances": {
                            "properties": {
                                "key": {
                                    "type": "text",
                                    "fields": {
                                        "keyword": {
                                            "type": "keyword",
                                            "ignore_above": 256
                                        }
                                    }
                                },
                                "value": {
                                    "type": "double"
                                }
                            }
                        },
                        "name": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "id": {
                            "type": "long"
                        }
                    }
                }
            }
        }
    }

源(_S)

    "_source": {
        "properties": [{
                "value": [
                    "D"
                ],
                "key": "M"
            },
            {
                "value": [
                    "2019-12-31"
                ],
                "key": "DOCUMENT_DATE"
            },
            {
                "isMultiValue": false,
                "value": [
                    "Yes"
                ],
                "key": "ACTIVE_DOCUMENT"
            },
        ],
        "performances": [
            {
                "value": 123,
                "key": "performance1"
            },
            {
                "value": 234,
                "key": "performance3"
            },
            {
                "value": 345,
                "key": "performance5"
            },
            {
                "value": -456,
                "key": "someKey"
            },
            {
                "value": -567,
                "key": "someOtherKey"
            },
        ],
        "name": "documentName43",
        "id": "1234"
    }

脚本如下所示:

    {
        "query": {
            "bool": {
                "filter": [{
                        "nested": {
                            "path": "properties",
                            "query": {
                                "bool": {
                                    "filter": [{
                                            "match": {
                                                "properties.key.keyword": "ACTIVE_DOCUMENT"
                                            }
                                        },
                                        {
                                            "match": {
                                                "properties.value": "yes"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    {
                        "match": {
                            "id": "1234"
                        }
                    }
                ]
            }
        },
        "script_fields": {
            "nested_scores": {
                "script": {
                    "lang": "painless",
                    "source": "for (int i = 0; i < params['_source']['performances'].length; ++i) { if(params['_source']['performances'][i]['key'] == params['customFields'][i]) { return params['_source']['performances'][i]['value'];}}return 0;",
                    "params": {
                        "customFields": ["performance1", "performance3", "performance5"]
                    }

                }
            }
        },
        "_source": [
            "id",
            "name",
            "name."
        ]
    }

如果我用一个简单的字符串替换“params['自定义字段'][I]”部分,它工作得很好,所以我猜我的问题就在那里,但不知道到底是什么。

另一个注意事项,知道如何构造我的查询,以便在“_source”中返回来自无痛脚本的结果吗?

最后,我想做这样的事情:

"source": "for (int i = 0; i < params['_source']['performances'].length; ++i) {
                            for (int t = 0; t < params['customFields'].length; ++t) {
                                if(params['_source']['performances'][i]['key'] == params['customFields'][t]) {
                                    return params['_source']['performances'][i]['value']; 
                                }
                            }
                          }
                          return 0;"

但首先我想让它使用上面的代码。

如果这很重要的话,我使用的是ES6.4,我首先尝试使用Chrome的插件“弹性搜索头”来运行查询。

然而,结果看起来是这样的(在上面的示例中,为了方便起见,我将一些字段如“Kennzahlen”更改为“properties”)

{
    "took": 679,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 4,
        "skipped": 0,
        "failed": 1,
        "failures": [{
            "shard": 0,
            "index": "fsl_prd_products",
            "node": "xAUFwT0LRVeAuOktIr9gaA",
            "reason": {
                "type": "script_exception",
                "reason": "runtime error",
                "script_stack": [
                    "java.util.ArrayList.rangeCheck(ArrayList.java:653)",
                    "java.util.ArrayList.get(ArrayList.java:429)",
                    "if (params['_source']['kennzahlen'][i]['key'] == params['customFields'][i]) { ",
                    " ^---- HERE"
                ],
                "script": "for (int i = 0; i < params['_source']['kennzahlen'].length; ++i) { if (!params['_source'].containsKey('kennzahlen')) { return 0; } if (params['_source']['kennzahlen'][i]['key'] == params['customFields'][i]) { return params['_source']['kennzahlen'][i]['value']; } } return 0;",
                "lang": "painless",
                "caused_by": {
                    "type": "index_out_of_bounds_exception",
                    "reason": "Index: 3, Size: 3"
                }
            }
        }]
    },
    "hits": {
        "total": 1,
        "max_score": 0,
        "hits": []
    }
}

共有1个答案

隆兴修
2023-03-14

script_fields的结果永远不会出现在响应的_source部分--它们总是分开的。

让我们使用ES 7.2.0复制您的用例:

设置索引+摄取(为了简洁,没有空格)

PUT docs
{"mappings":{"properties":{"properties":{"type":"nested","properties":{"key":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"value":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},"performances":{"properties":{"key":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"value":{"type":"double"}}},"name":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"id":{"type":"long"}}}}

POST docs/_doc
{"properties":[{"value":["D"],"key":"M"},{"value":["2019-12-31"],"key":"DOCUMENT_DATE"},{"isMultiValue":false,"value":["Yes"],"key":"ACTIVE_DOCUMENT"}],"performances":[{"value":123,"key":"performance1"},{"value":234,"key":"performance3"},{"value":345,"key":"performance5"},{"value":-456,"key":"someKey"},{"value":-567,"key":"someOtherKey"}],"name":"documentName43","id":"1234"}

然后搜索

GET docs/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "properties",
            "query": {
              "bool": {
                "filter": [
                  {
                    "match": {
                      "properties.key.keyword": "ACTIVE_DOCUMENT"
                    }
                  },
                  {
                    "match": {
                      "properties.value": "yes"
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "match": {
            "id": "1234"
          }
        }
      ]
    }
  },
  "script_fields": {
    "nested_scores": {
      "script": {
        "lang": "painless",
        "source": """
          for (int i = 0; i < params['_source']['performances'].length; ++i) { 
            if (params['_source']['performances'][i]['key'] == params['customFields'][i]) { 
              return params['_source']['performances'][i]['value'];
            }

          }
          return 0;
        """,
        "params": {
          "customFields": [
            "performance1",
            "performance3",
            "performance5"
          ]
        }
      }
    }
  },
  "_source": [
    "id",
    "name",
    "name."
  ]
}

系统产生

[
  {
    "_index":"docs",
    "_type":"_doc",
    "_id":"vOhj8HEBG_KW3EFn7wOf",
    "_score":0.0,
    "_source":{
      "name":"documentName43",
      "id":"1234"
    },
    "fields":{
      "nested_scores":[            <-------
        123
      ]
    }
  }
]

如果查询失败,您可能希望尝试一些有效性检查:

...
"source": """
          if (!params['_source'].containsKey('performances')) {
            return 0
          }
          // rest of the script
"""
...

不过,我不确定你想做什么。如果满足循环中的条件,它将返回第一个匹配项。因此,它可能永远不会运行,除非perf3perf5...此外,_source.performations可能没有排序,因此,相反,它可能返回perf5并退出。

 类似资料:
  • 我没有Java经验,我对elasticsearch无痛脚本语言有问题。(这个名字叫“无痛”,选得不好)。 对于下面的代码,我得到了错误: 无法应用 [ 我用(float) doc['newPrice']将它绑定为float 然后我改为<code>“Double price=((Double)doc['discountPrice'] 并收到: “无法从[双]铸造到[双]。” 有人可以帮助我,尝试了很

  • 我有一个扩展类的类,它看起来像: 问题是,我可以向添加自定义吗?我浏览了和中可用的所有方法,但没有找到任何方法。但是在模式下,我发现在中有的列表。如何在此添加自定义?

  • 是否有一种方法可以使用来完成这一任务,而不需要为每个Patamenter组合创建大量/语句?

  • 我想从特定字段中搜索关键字并返回文档。在这些文档之上,我希望遍历每个嵌套对象,并从选定文档的同一特定字段中再次搜索关键字。 如果关键字存在,则检查:如果布尔isCurrent = True,则设置isCurrent=0,并将该值追加到列表中;否则,如果isCurrent = False,则取当前日期时间的差值,结束日期时间,并获得以月为单位的值,并将该值追加到列表中。 最后,从每个文档的列表中获取

  • 存储在Django模型中的元素如下 示例数据如下: . 结果:找到对象- 结果:找到对象- 结果:找到对象- 结果:未找到对象 如何使用过滤器和正则表达式进行这些查询?

  • 我正在使用高级自定义字段插件,我试图通过分类字段过滤一些自定义帖子,修改WP_Query: 如果我尝试通过文本字段过滤一切正常,WP_Query被修改。但是当字段是一个分类法字段时,我不知道应该传递什么参数,因为它是一个对象。我尝试了分类法名称和分类法ID,但不起作用。 是否可以通过分类字段进行筛选?我应该传递的什么参数?谢谢! 更新-结构: 自定义帖子:“递归操作系统” 自定义分类Slug:'r