Scripted field return value on same order than original

I am trying to create a scripted field to be able to fetch me the first value of a certain field.
I find the problem in that when it returns the values ​​of the field, and I save them in path, it sorts them alphabetically in such a way that when choosing the zero value later, this is sometimes not the one I want.

I would like to get the values ​​in the same order as in the original field.

//
 if (!doc.containsKey('RSLT') || doc['RSLT'].empty){
    return ""
}else{
    def list = [];  
    for(int i=0; i < doc['RSLT'].length;i++){
        def path=doc['RSLT'][i];
        int lastSlashIndex = path.lastIndexOf(':');
        if (lastSlashIndex > 0) {    
            list.add(path.substring(lastSlashIndex+1));
        }else {
            list.add(path);
        }
            
    }
    return list[0];
}
//

Can you make an example (with input and output) of what you would like to achieve vs what you are seeing with the current version of the script? It's not clear to me from the screenshot you posted.

If original  field = {route:INCIDENCIA_TECNICA_ADSL}, {route:ADSL_CONCRETAR} 
I want to get value  in position 0   INCIDENCIA_TECNICA_ADSL
but I obtain ADSL_CONCRETAR because : def path=doc['RSLT'][i] order the values.

Thanks

Ah got it, thanks. As you can see here lucene - Does Elasticsearch keep an order of multi-value fields? - Stack Overflow

The order of indexed multi value fields is not guaranteed.

You can get around that by accessing the _source object: Accessing document fields and special variables | Elasticsearch Reference [master] | Elastic

Hi Joe:

could you help me with the script? I don't know how to enter the new parameter that you tell me to make it work for me.
I do not have much experience with painless and all help is great

Regards

Let's say your document looks like this:

{
  "extension": ["gz", "css"]
}

Then the following scripted field will return "gz":

return params._source.extension[0]

When I adapt the script that you advised me:

Captura de pantalla 2021-03-04 155513

It throws me the following error:

When searching in dev tools with the following query:

Captura de pantalla 2021-03-04 155333

I get:

It seems like a format like the one you indicated but nevertheless I keep getting errors and I don't get the data the way I want

Any suggestion.

Thanks

Either make sure every document in your index specified an array for "RSLT" or add a check in the script:

if (params._source.RSLT instanceof List) {
  ...
} else {
  return null;
}

When I adapt your script:

Captura de pantalla 2021-03-04 171130

Give me the next error:

You have a typo there - it says soource

Upss!!!

I changed it and it works!!

But now some values in position[0] are liki this:

image

How I could split them by '#' and obtain the first value??

Thanks!!

It's still painless, you can use the same approach as in your original script

I don´t understand

Sorry

The scripted field is defined using the painless programming language, and extracting a part of a string is a simple task in this programming language. See the official guide for how to do string manipulation: Painless Guide | Painless Scripting Language [7.11] | Elastic

The script in your original question is pretty close to what you need.

I won't write your script for you, please check out the tutorials to learn how to use the painless programming language for this kind of simple tasks.

With this script:

if (params._source.RSLT instanceof List) {
     def list = [];  
    for(int i=0; i < params._source['RSLT'].length;i++){
        def path=params._source['RSLT'][i];
        path = path.replace('#',',');
        int lastSlashIndex = path.lastIndexOf(',');
        if (lastSlashIndex > 0) {    
            list.add(path.substring(lastSlashIndex+1));
        }else {
            list.add(path);
        }
    }
    return list[0];
} else {
    return params._source['RSLT'];
    }

I get the value that I'm looking for most of the time

But when :

......
else {
    return params._source['RSLT'];
    }

return:

I don't know how to split it by '#' and keep the first value while keeping the order.

Any suggestion

Thanks

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