2017-08-30 1 views
0

Sur Kibana, je peux afficher les journaux de divers produits (product.name) avec l'horodatage et d'autres informations. Voici l'un des journaux:Requête ELK pour renvoyer un enregistrement pour chaque produit avec l'horodatage maximal

{ 
    "_index": "xxx-2017.08.30", 
    "_type": "logs", 
    "_id": "xxxx", 
    "_version": 1, 
    "_score": null, 
    "_source": { 
    "v": "1.0", 
    "level": "INFO", 
    "timestamp": "2017-01-30T18:31:50.761Z", 
    "product": { 
     "name": "zzz", 
     "version": "2.1.0-111" 
    }, 
    "context": { 
     ... 
     ... 
    } 
    }, 
    "fields": { 
    "timestamp": [ 
     1504117910761 
    ] 
    }, 
    "sort": [ 
    1504117910761 
    ] 
} 

Il existe plusieurs autres journaux pour le même produit et plusieurs journaux pour différents produits.

Cependant, je souhaite écrire une requête qui renvoie un enregistrement unique pour un nom de produit donné (celui avec la valeur d'horodatage maximale) et renvoie la même information pour tous les autres produits. Cela, est que les logs sont retournés un pour chaque produit et pour chaque produit, ce devrait être celui avec un horodatage maximum.

Comment puis-je y parvenir?

J'ai essayé de suivre l'approche figurant dans: How to get latest values for each group with an Elasticsearch query?

et a créé une requête:

{ 
    "aggs": { 
     "group": { 
      "terms": { 
       "field": "product.name" 
      }, 
      "aggs": { 
       "group_docs": { 
        "top_hits": { 
         "size": 1, 
         "sort": [ 
          { 
           "timestamp": { 
            "order": "desc" 
           } 
          } 
         ] 
        } 
       } 
      } 
     } 
    } 
}' 

Mais, je suis une erreur qui dit:

"error" : { 
    "root_cause" : [ 
     { 
     "type" : "illegal_argument_exception", 
     "reason" : "Fielddata is disabled on text fields by default. Set fielddata=true on [product.name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead." 
     } 
    ], 

Ai-je absolument besoin de définir fielddata = true pour ce champ dans ce cas? Si non, que dois-je faire? Si oui, je ne suis pas sûr de savoir comment le définir. Je l'ai essayé de faire de cette façon:

curl -XGET 'localhost:9200/xxx*/_search?pretty' -H 'Content-Type: application/json' -d' 
{ 
    "properties": { 
     "product.name": { 
     "type":  "text", 
     "fielddata": true 
     } 
    }, 
    "aggs": { 
     "group": { 
      "terms": { 
       "field": "product.name" 
      }, 
      "aggs": { 
       "group_docs": { 
        "top_hits": { 
         "size": 1, 
         "sort": [ 
          { 
           "timestamp": { 
            "order": "desc" 
           } 
          } 
         ] 
        } 
       } 
      } 
     } 
    } 
}' 

Mais, je pense qu'il ya quelque chose de mal avec elle et je reçois cette erreur (synatactically?):

{ 
    "error" : { 
    "root_cause" : [ 
     { 
     "type" : "parsing_exception", 
     "reason" : "Unknown key for a START_OBJECT in [properties].", 
     "line" : 3, 
     "col" : 19 
     } 
    ], 

Répondre

0

La raison pour laquelle vous avez obtenu l'erreur est parce que vous essayez Pour effectuer l'agrégation sur le champ de texte (product.name), vous ne pouvez pas le faire dans elasticsearch 5. Vous n'avez pas besoin de définir les données de champ sur true, ce que vous devez faire est de définir dans le mappage du produit fields. nom comme 2 champs, un product.name et deuxième product.name.keyword Comme ceci:

{ 
"product.name": 
     { 
     "type" "text", 
      "fields": 
      { 
       "keyword": 
        { 
        "type": "keyword", 
        "ignore_above": 256 
        } 
      } 
     } 
    } 

Ensuite, vous devez faire l'agrégation sur product.name.keyword

+0

Lax, j'avais juste enfait essayé de remplacer "field": "product.name" dans ma requête ci-dessus à "field": "product.name.keyword" après avoir posté cette question et qui était au moins pas défaillant et semblait renvoyer des enregistrements corrects. Avons-nous vraiment besoin d'utiliser toute la grosse section ci-dessus comme vous l'avez écrit ci-dessus au lieu de simplement remplacer product.name par product.name.keywrod? Si oui, pourquoi? Et comment puis-je inclure cela dans ma requête actuelle ci-dessus? – user1892775

+0

Toute la grande section doit être dans votre schéma. S'il vous plaît poster votre schéma – Lax