Access nested array objects in script query


(Yoran Petrovic) #1

Hi, I'm having some trouble with a nested scripted query. I'll just quickly explain what I'm trying to achieve:

I have objects like:

{
    "metaData": {
        "meta": [
            {
                "key": "width",
                "value": 10
            },
            {
                "key": "height",
                "value": 104
            },
            {
                "key": "etc",
                "value": 1056
            }
        ]
    }
}

This is the mapping:

"properties": {
            "metaData": {
                "properties": {
                    "meta": {
                        "type": "nested",
                        "properties": {
                            "key": {
                                "type": "keyword"
                            },
                            "value": {
                                "type": "long"
                            }
                        }
                    }
                }
            }
        }

Now I need a query that will only return documents where f.e. the value field of the nested object with key "width" is greater than the value field of the nested object with key "height".

I am attempting this with a nested query and a script query like this:

    {
    "query": {
        "nested": {
            "path": "metaData.meta",
            "query": {
                "script": {
                    "script": "if (doc['metaData.meta'].length < 1) return false; int width; int height; for(int i=0; i< doc['metaData.meta'].length; i++) {  if (doc['metaData.meta'][i].key == 'width') {width=doc['metaData.meta'][i].valueDec;} else if (doc['metaData.meta'][i].key == 'height') {height=doc['metaData.meta'][i].valueDec;} } return width > height"
                }
            }
        }
    }
}

Now with this approach i would need access to each nested object in the for loop, but this error is thrown: No field found for [metaData.meta] in mapping with types [type].

Anyone who knows how I could better approach this without changing the mapping/ structure of the document?


(Alexander Reelsen) #2

Have you thought of using an ingest processor that checks the value height and width at index time and stores the result in another field? Then you would have fast queries as you do not need to run an expensive script query at all.

Of course this only makes sense if you have a limited number of such checks.

--Alex


(Yoran Petrovic) #3

Hi Alex, thanks for your reply, this would be a solution, but the problem with the ingest node is that it only acts upon initial index operations and not on update operations. These values may change in the future and it would also require a complete reindex of our current data, which is not very handy at the moment.


(system) closed #4

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.