Painless Script (Miscellaneous functions)

Hello,

I have an issue with this painless script file in (/etc/elasticsearch/scripts) to create an entity centric index :

//------------------------------------------------------- ----------------------------------------------------------

  def docSrc = ctx._source;
  def codeStatusSuccess_1 = "200";
  def iOS = "1";
  def Android = "2";
  def Web = "3";

//------------------------------------------------------- ----------------------------------------------------------

  if("create".equals(ctx.op)){
    //initialize entity state
    docSrc.Field1 = [];
  }

//------------------------------------------------------- ----------------------------------------------------------

    def req1Map =[:];
    for (req1 in docSrc.Field1) {
      req1Map[req1.id]=req1;
    }

//------------------------------------------------------- ----------------------------------------------------------

    for (event in params.events) {
      def req1 =req1Map[event.id];
      if(req1 ==null){
        req1=[
          "id": event.id,
          "login": event.login,
          "statusCode": event.statusCode,
          "media": event.media,
          "createdAt": event.created_at,
          "countEvent": 1
        ];
        req1Map[req1.id]=req1;
      }else{
        req1.countEvent ++;
      }
    }

//------------------------------------------------------- ----------------------------------------------------------

    docSrc.Field1 = req1Map.values();

//------------------------------------------------------- ----------------------------------------------------------
    def nbAllReq = 0;
    def login;
    def totalReq = 0;
    def nbAndroidSuccessReq = 0;
    def nbAndroidErrorsReq = 0;
    def nbWebSuccessReq = 0;
    def nbWebErrorsReq = 0;
    def nbiOSSuccessReq = 0;
    def nbiOSErrorsReq = 0;
    def nbUnknownSuccessReq = 0;
    def nbUnknownErrosReq = 0;


    for (req1 in docSrc.Field1){
      nbAllReq += req1.countEvent;
      login = req1.login;

    }

 for (req1 in docSrc.Field1){
      if (req1.media == Android && req1.statusCode == codeStatusSuccess_1){
            nbAndroidSuccessReq += req1.countEvent;
            **FirstAnrdoidSuccessIDreq** =
            **LastAndroidSuccessIDreq** =
            **DateFirstAndroidSuccessReq** =
            **DateLastAnrdoidSuccessReq** =
      } 
      else if (req1.media == Android && req1.statusCode){
            nbAndroidErrorsReq += req1.countEvent;
            **FirstAndroidFailedIDreq** =
            **LastAndroidFailedIDreq** =
            **DateFirstAndroidFailedReq** =
            **DateLastAnrdoidFailedReq** =
      }
      else if (req1.media == Web && req1.statusCode == codeStatusSuccess_1){
            nbWebSuccessReq += req1.countEvent;
            **FirstWebSuccessIDreq** =
            **LastWebSuccessIDreq** =
            **DateFirstWebSuccessReq** =
            **DateLastWebSuccessReq** =
      }
      else if (req1.media == Web && req1.statusCode != codeStatusSuccess_1){
            nbWebErrorsReq += req1.countEvent;
            **FirstWebFailedIDreq** =
            **LastWebFailedIDreq** =
            **DateFirstWebFailedReq** =
            **DateLastWebFailedReq** =
      }
      else if (req1.media == iOS && req1.statusCode == codeStatusSuccess_1){
            nbiOSSuccessReq += req1.countEvent;
            **FirstiOSSuccessIDreq** =
            **LastiOSSuccessIDreq** =
            **DateFirstiOSSuccessReq** =
            **DateLastiOSSuccessReq** =
      }
      else if (req1.media == iOS && req1.statusCode != codeStatusSuccess_1){
            nbiOSErrorsReq += req1.countEvent;
            **FirstiOSFailedIDreq** =
            **LastiOSFailedIDreq** =
            **DateFirstiOSFailedReq** =
            **DateLastiOSFailedReq** =
      }
      else if ((req1.media != iOS || req1.media != Android || req1.media != Web) && (req1.statusCode == codeStatusSuccess_1)){
            nbUnknownSuccessReq += req1.countEvent;
            **FirstUnknownSuccessIDreq** =
            **LastUnknownSuccessIDreq** =
            **DateFirstUnknownSuccessReq** =
            **DateLastUnknownSuccessReq** =
      }
      else{
            nbUnknownErrosReq += req1.countEvent;
            **FirstUnknownFailedIDreq** =
            **LastUnknownFailedIDreq** =
            **DateFirstUnknownFailedReq** =
            **DateLastUnknownFailedReq** =
      }
    }

//------------------------------------------------------- ----------------------------------------------------------
    
    docSrc.nbAllReq = nbAllReq;
    docSrc.login = login;
    docSrc.nbAndroidSuccessReq = (int)nbAndroidSuccessReq;
    docSrc.nbAndroidErrorsReq = (int)nbAndroidErrorsReq;
    docSrc.nbWebSuccessReq = (int)nbWebSuccessReq;
    docSrc.nbWebErrorsReq = (int)nbWebErrorsReq;
    docSrc.nbiOSSuccessReq = (int)nbiOSSuccessReq;
    docSrc.nbiOSErrorsReq = (int)nbiOSErrorsReq;
    docSrc.nbUnknownSuccessReq = (int)nbUnknownSuccessReq;
    docSrc.nbUnknownErrosReq = (int)nbUnknownErrosReq;

I would like to get in every loop the Max, Min created_at field (date) and Max,Min id field (int).
(How to use Max, Min, Unique Count ... functions for integer and date values).
Could you please give me a good reference or doc on painless language for elasticsearch?

Example of output :

   "nbUnknownErrosReq": 0,
   "nbAllReq": 101,
   "nbiOSErrorsReq": 0,
   "nbAndroidErrorsReq": 0,
   "nbWebErrorsReq": 1,
   "nbWebSuccessReq": 100,
   "nbUnknownSuccessReq": 0,
   "nbAndroidSuccessReq": 0,
   "FirstWebSuccessIDreq" : 101
   "LastWebSuccessIDreq" : 200
   "DateFirstWebSuccessReq" : "2017-07-01T12:20:30"  
   "DateLastWebSuccessReq" : "2017-07-10T23:11:34"
   "FirstWebFailedIDreq" : 122
   "LastWebFailedIDreq" : 122
   "DateFirstWebFailedReq" : "2017-07-6T8:32:12"
   "DateLastWebFailedReq" : "2017-07-6T8:32:12"

Thank you in advance

Max would be done using Math.max e.g.

for (event in params.events){
  docSrc.Field1 = Math.max(docSrc.Field1, event.count);
}

(See the "Math" object in the API reference )

Unique count might be a bit more challenging to implement. Be aware that there is a limit on painless script sizes currently and you shouldn't be too ambitious in how much complexity to implement in such a script. Writing a native Java update script plugin may be a better option when things get too complex.

Thanks for answer.
Is it possible to make a Max or Min on an array (not only between 2 arguments).

Thank you in advance.

Java does not provide min or max on an array. You would need to loop through the values, calling min or max on your current min/max and the next value.

To get the Min and Max values, i neet to make a sort (Asc or Desc) on my id field.
How to do that please?

Sorry, I don't understand what you are asking. You do not need to sort in order to find min/max of a list of values.

"nbAndroidSuccessReq": 0,
"nbUnknownErrorsReq": 379,
"Field1": [
{
"countEvent": 1,
"id": 19350830
},
{
"countEvent": 1,
"id": 19350828
},
{
"countEvent": 1,
"id": 19350827
},
{
"countEvent": 1,
"id": 19350826
},
{
"countEvent": 1,
"id": 19872063
},
{
"countEvent": 1,
"id": 19872061
},
{
"countEvent": 1,
"id": 19872058
},
{
"countEvent": 1,
"id": 20501806
},
{

How to create a painless code to get Min and Max ID in this example.

Those are nested docs, which are not accessible within scripts. You would need to have all the values in an actual field (in your example Field1 is not a concrete field, it is a nested field).

Thank you very much for your help

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