Я пытаюсь создать безболезненный скрипт для фильтрации массива вложенных полей с помощью массива настраиваемых параметров, по моему for l oop выдает ошибку.
Сопоставление
{
"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"
}
}
}
}
}
}
_source
"_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 ['customFields '] [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;"
Но сначала я хотел заставить его работать с приведенным выше кодом.
Я использую ES 6.4, если это имеет значение, и сначала я пытаюсь выполнить запрос, используя «elasticsearch-head» chrome plugin.
Однако результат выглядит примерно так (я изменил некоторые поля, такие как «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": []
}
}