2016-07-20 8 views
1

Ich habe unten Mapping in meinem Index:Verwendung Maximalwert von verschachtelten Array für sum Aggregation in Elasticsearch

{ 
"testIndex": { 
    "mappings": { 
     "type1": { 
      "properties": { 
       "text": { 
        "type": "string" 
       }, 
       "time_views": { 
        "type": "nested", 
        "properties": { 
         "timestamp": { 
          "type": "long" 
         }, 
         "views": { 
          "type": "integer" 
         } 
        } 
       } 
      } 
     } 
    } 
} 
} 

eigentlich "time_views" ist ein Array, aber innere Attribute nicht-Array. Dieser geschachtelte Typ enthält den Verlauf der Anzahl der Aufrufe von Typ1. "Ansichten" ist ein kumulatives Attribut.

Ich möchte in meinem Dokument abfragen, die Summe von "Ansichten" aller Dokumente abrufen, die ein beliebiges Wort in "Text" -Feld in diesen Dokumenten auftritt.

Ich weiß, ich sollte Aggregation verwenden, aber ich weiß nicht, wie für diese Abfrage.

{ 
    "query": { 
     "term":{ 
      "text": "anyword" 
     } 
    }, 
    "size": 0, 
    "aggs":{ 
     ??? 
    } 
} 

wie ich oben „time_views“ erwähnt ist ein Array für jedes Dokument und ich möchte nur den Maximalwert von „Ansichten“ jedes Arrays verwenden.

Beispieldaten

{ 
    "text": "red car", 
    "time_views": [ 
     { 
      "timestamp": 1651116565, 
      "views": 100 
     }, 
     { 
      "timestamp": 1651546456, 
      "views": 153 
     }, 
     { 
      "timestamp": 165446456, 
      "views": 200 
     } 
    ] 
}, 
{ 
    "text": "blue car", 
    "time_views": [ 
     { 
      "timestamp": 1651116565, 
      "views": 20 
     }, 
     { 
      "timestamp": 1651546456, 
      "views": 70 
     }, 
     { 
      "timestamp": 165446456, 
      "views": 130 
     } 
    ] 
}, 
{ 
    "text": "green car", 
    "time_views": [ 
     { 
      "timestamp": 1651116565, 
      "views": 4 
     }, 
     { 
      "timestamp": 1651546456, 
      "views": 86 
     }, 
     { 
      "timestamp": 165446456, 
      "views": 100 
     } 
    ] 
} 

Ich erwarte, dass unten Ergebnis zu erhalten, wenn ich für "Auto" abfragen:

{ 
    "text": "car" 
    "views": 430 
} 

wo 430 = 200 (max-Wert im ersten doc) + 130 (maximaler Wert im zweiten Dokument) + 100 (maximaler Wert im dritten Dokument)

Ich interessiere mich nicht für JSON-Struktur von dem Ergebnis brauche ich nur die Information.

Was soll ich tun? tnx :)

+0

Können Sie auch ein paar Beispieldokumente teilen und was Sie erwarten wieder in der Antwort zu bekommen? – Val

+0

@Val Ich habe einige Beispieldaten hinzugefügt und das Ergebnis, dass ich erwarte –

+0

Ich habe meine Antwort gelöscht, da es scheint, dass es Ihr Problem nicht gelöst hat. Persönlich glaube ich nicht, dass es möglich ist, ohne ein separates Feld/Objekt "max_view" zum Root-Dokument hinzuzufügen, das das maximale View-Objekt enthalten würde, das Sie zum Indexzeitpunkt liefern müssten – mbudnik

Antwort

2

nach vielen Suchen habe ich endlich eine Lösung gefunden. Ich benutzte "scripted_metric" Aggregation und schreibe eine benutzerdefinierte. hier ist mein Code

{ 
    "query": { 
    "term": { 
     "text": "car" 
    } 
}, 
"aggs": { 
    "views_sum": { 
     "scripted_metric": { 
      "init_script": "_agg['maximum'] = []", 
      "map_script": "max = _source.time_views[0].views; for(tv in _source.time_views){ if(tv.views > max){max = tv.views; }}; _agg.maximum.add(max);", 
      "combine_script": "sum = 0; for (m in _agg.maximum) { sum += m }; return sum;", 
      "reduce_script": "sum = 0; for (a in _aggs) { sum += a }; return sum;" 
     } 
    } 
}, 
"size": 0 
} 

und das ist mein Ergebnis:

{ 
"took": 3, 
"timed_out": false, 
"_shards": { 
    "total": 5, 
    "successful": 5, 
    "failed": 0 
}, 
"hits": { 
    "total": 3, 
    "max_score": 0, 
    "hits": [] 
}, 
"aggregations": { 
    "views_sum": { 
     "value": 430 
    } 
} 
} 
Verwandte Themen