2017-04-27 1 views
1

Je voudrais savoir s'il existe un moyen de faire quelque chose qui s'apparente à bucket_selector mais en testant sur la base d'une correspondance de clé au lieu d'une métrique numérique.Elasticsearch agrégation de l'agrégation

Pour donner un peu plus de contexte, voici mon cas d'utilisation:

échantillon de données:

[ 
    { 
    "@version": "1", 
    "@timestamp": "2017-04-27T04:28:23.589Z", 
    "type": "json", 
    "headers": { 
     "message": { 
     "type": "requestactivation" 
     } 
    }, 
    "id": "668" 
    }, 
    { 
    "@version": "1", 
    "@timestamp": "2017-04-27T04:32:23.589Z", 
    "type": "json", 
    "headers": { 
     "message": { 
     "type": "requestactivation" 
     } 
    }, 
    "id": "669" 
    }, 
    { 
    "@version": "1", 
    "@timestamp": "2017-04-27T04:30:00.802Z", 
    "type": "json", 
    "headers": { 
     "message": { 
     "type": "activationrequested" 
     } 
    }, 
    "id": "668" 
    } 
] 

Je voudrais récupérer tous les ids où le dernier événement est de type requestactivation.

J'ai déjà une agrégation qui récupère le dernier type d'événement par id, mais je n'ai pas compris comment filtrer des seaux en fonction de la clé

Voici la requête:

{ 
    "size": 0, 
    "query": { 
    "bool": { 
     "filter": [ 
     { 
      "exists": { 
      "field": "id" 
      } 
     }, 
     { 
      "terms": { 
      "headers.message.type": [ 
       "requestactivation", 
       "activationrequested" 
      ] 
      } 
     } 
     ] 
    } 
    }, 
    "aggs": { 
    "id": { 
     "terms": { 
     "field": "id", 
     "size": 10000 
     }, 
     "aggs": { 
     "latest": { 
      "max": { 
      "field": "@timestamp" 
      } 
     }, 
     "hmtype": { 
      "terms": { 
      "field": "headers.message.type", 
      "size": 1 
      } 
     } 
     } 
    } 
    } 
} 

Voici un exemple de résultat:

{ 
    "took": 5, 
    "timed_out": false, 
    "_shards": { 
    "total": 3, 
    "successful": 3, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 3, 
    "max_score": 0, 
    "hits": [] 
    }, 
    "aggregations": { 
    "id": { 
     "doc_count_error_upper_bound": 3, 
     "sum_other_doc_count": 46, 
     "buckets": [ 
     { 
      "key": "986", 
      "doc_count": 4, 
      "hmtype": { 
      "doc_count_error_upper_bound": 0, 
      "sum_other_doc_count": 2, 
      "buckets": [ 
       { 
       "key": "activationrequested", 
       "doc_count": 2 
       } 
      ] 
      }, 
      "latest": { 
      "value": 1493238253603, 
      "value_as_string": "2017-04-26T20:24:13.603Z" 
      } 
     }, 
     { 
      "key": "967", 
      "doc_count": 2, 
      "hmtype": { 
      "doc_count_error_upper_bound": 0, 
      "sum_other_doc_count": 1, 
      "buckets": [ 
       { 
       "key": "requestactivation", 
       "doc_count": 1 
       } 
      ] 
      }, 
      "latest": { 
      "value": 1493191161242, 
      "value_as_string": "2017-04-26T07:19:21.242Z" 
      } 
     }, 
     { 
      "key": "554", 
      "doc_count": 7, 
      "hmtype": { 
      "doc_count_error_upper_bound": 0, 
      "sum_other_doc_count": 5, 
      "buckets": [ 
       { 
       "key": "requestactivation", 
       "doc_count": 5 
       } 
      ] 
      }, 
      "latest": { 
      "value": 1493200196871, 
      "value_as_string": "2017-04-26T09:49:56.871Z" 
      } 
     } 
     ] 
    } 
    } 
} 

Toutes les applications ne sont pas analysés (mot-clé).

L'objectif serait de réduire les résultats uniquement à ceux où la clé dans le bucket est "requestactivation".

Le nombre de documents ne peut pas être utilisé car la demande d'activation peut apparaître plusieurs fois pour un ID.

Ce n'est que récemment que nous avons commencé à explorer les agrégations, donc, si la question semble évidente, les exemples ne semblaient pas correspondre à cette logique spécifique.

Répondre

1

Que diriez-vous include utilisé dans une agrégation terms de « filtrer » les valeurs incluses dans les termes à seulement pertinent pour la demande:

{ 
    "size": 0, 
    "query": { 
    "bool": { 
     "filter": [ 
     { 
      "exists": { 
      "field": "id" 
      } 
     }, 
     { 
      "terms": { 
      "headers.message.type": [ 
       "requestactivation", 
       "activationrequested" 
      ] 
      } 
     } 
     ] 
    } 
    }, 
    "aggs": { 
    "id": { 
     "terms": { 
     "field": "id", 
     "size": 10000 
     }, 
     "aggs": { 
     "latest": { 
      "max": { 
      "field": "@timestamp" 
      } 
     }, 
     "hmtype": { 
      "filter": { 
      "terms": { 
       "headers.message.type": [ 
       "requestactivation", 
       "activationrequested" 
       ] 
      } 
      }, 
      "aggs": { 
      "count_types": { 
       "cardinality": { 
       "field": "headers.message.type" 
       } 
      } 
      } 
     }, 
     "filter_buckets": { 
      "bucket_selector": { 
      "buckets_path": { 
       "totalTypes":"hmtype > count_types" 
      }, 
      "script": "params.totalTypes == 2" 
      } 
     } 
     } 
    } 
    } 
} 
+0

je pourrais manquer quelque chose, mais tester le projet comprennent je finis avec tous les identifiants qui ont des événements "activation demandée" (de votre exemple, je suis en train de chercher le "requestactivation"), ceci que l'id ait ou non l'autre type d'événement. – Olivier

+0

Mon mauvais, il devrait être '" include ":" requestactivation "' ... mais j'ai le sentiment qu'il y a quelques restrictions sur le chemin. –

+0

Mais l'inclusion agit fondamentalement de la même manière que si j'avais filtré les ** événements ** demandés par activation dans la requête (car je ne me soucie pas des résultats de requêtes par exemple). alors que j'aimerais filtrer les ** identifiants ** pour lesquels une activation demandée a été reçue. – Olivier