2014-09-23 20 views
11

ich einige Dokumente haben:Elasticsearch Filter Dokumentengruppe von Feld

{"name": "John", "district": 1}, 
{"name": "Mary", "district": 2}, 
{"name": "Nick", "district": 1}, 
{"name": "Bob", "district": 3}, 
{"name": "Kenny", "district": 1} 

Wie kann ich verschiedene Dokumente, die von Bezirk filtern/wählen?

{"name": "John", "district": 1}, 
{"name": "Mary", "district": 2}, 
{"name": "Bob", "district": 3} 

In SQL kann ich GROUP BY verwenden. Ich versuchte Begriffe Aggregation, aber es gab nur Zählung deutlich.

"aggs": { 
    "distinct": { 
    "terms": { 
     "field": "district", 
     "size": 0 
    } 
    } 
} 

Dank für Ihre Hilfe! :-)

+0

Ist meine Antwort Lösen Sie Ihr Problem –

Antwort

29

Wenn Ihre Elasticsearch Version 1.3 oder höher ist, können Sie eine subaggregation vom Typ umwandeln können top_hits verwenden Dadurch erhalten Sie (standardmäßig) die drei besten übereinstimmenden Dokumente, die nach Ihrer Suchanfrage sortiert sind (hier 1, wenn Sie eine Suchanfrage match_all verwenden).

Sie können das size Parameter auf mehr als 3

Die folgenden Daten-Set und query:

POST /test/districts/ 
{"name": "John", "district": 1} 

POST /test/districts/ 
{"name": "Mary", "district": 2} 

POST /test/districts/ 
{"name": "Nick", "district": 1} 

POST /test/districts/ 
{"name": "Bob", "district": 3} 

POST test/districts/_search 
{ 
    "size": 0, 
    "aggs":{ 
    "by_district":{ 
     "terms": { 
     "field": "district", 
     "size": 0 
     }, 
     "aggs": { 
     "tops": { 
      "top_hits": { 
      "size": 10 
      } 
     } 
     } 
    } 
    } 
} 

Will Ausgabe der Dokumente, wie Sie wollen:

{ 
    "took": 5, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 4, 
     "max_score": 0, 
     "hits": [] 
    }, 
    "aggregations": { 
     "by_district": { 
     "buckets": [ 
      { 
       "key": 1, 
       "key_as_string": "1", 
       "doc_count": 2, 
       "tops": { 
        "hits": { 
        "total": 2, 
        "max_score": 1, 
        "hits": [ 
         { 
          "_index": "test", 
          "_type": "districts", 
          "_id": "XYHu4I-JQcOfLm3iWjTiOg", 
          "_score": 1, 
          "_source": { 
           "name": "John", 
           "district": 1 
          } 
         }, 
         { 
          "_index": "test", 
          "_type": "districts", 
          "_id": "5dul2XMTRC2IpV_tKRRltA", 
          "_score": 1, 
          "_source": { 
           "name": "Nick", 
           "district": 1 
          } 
         } 
        ] 
        } 
       } 
      }, 
      { 
       "key": 2, 
       "key_as_string": "2", 
       "doc_count": 1, 
       "tops": { 
        "hits": { 
        "total": 1, 
        "max_score": 1, 
        "hits": [ 
         { 
          "_index": "test", 
          "_type": "districts", 
          "_id": "I-9Gd4OYSRuexhP1dCdQ-g", 
          "_score": 1, 
          "_source": { 
           "name": "Mary", 
           "district": 2 
          } 
         } 
        ] 
        } 
       } 
      }, 
      { 
       "key": 3, 
       "key_as_string": "3", 
       "doc_count": 1, 
       "tops": { 
        "hits": { 
        "total": 1, 
        "max_score": 1, 
        "hits": [ 
         { 
          "_index": "test", 
          "_type": "districts", 
          "_id": "bti2y-OUT3q2mBNhhI3xeA", 
          "_score": 1, 
          "_source": { 
           "name": "Bob", 
           "district": 3 
          } 
         } 
        ] 
        } 
       } 
      } 
     ] 
     } 
    } 
} 
+0

Ausgezeichnet, du rettest mein Leben !! – Geany

+0

Hey @ThomasC, eine Idee, wie man auch Datensätze filtert, die so aggregiert werden sollen? Ich versuche es schon eine halbe Stunde. Vielen Dank ! – lisak

+0

Hallo @lisak! Sie können eine Aggregation nicht unter einem top_hits verschachteln, jedoch ist das Gegenteil möglich. Versuchen Sie es mit einer Filteraggregation und verschachteln Sie einen top_hits unter. Oder Sie können die Ergebnisse im Abfragebereich filtern – ThomasC

2

Die elastische Suche bietet keine eindeutigen Dokumente zu Wert oder Gruppe durch eindeutigen Wert. Aber es gibt Arbeit um für diese Sie dies tun können, wenn Sie Java-Client verwenden oder es in Ihrer geeigneten Sprache

SearchResponse response = client.prepareSearch().execute().actionGet(); 
SearchHits hits = response.getHits(); 

Iterator<SearchHit> iterator = hits.iterator(); 
Map<String, SearchHit> distinctObjects = new HashMap<String,SearchHit>(); 
while (iterator.hasNext()) { 
    SearchHit searchHit = (SearchHit) iterator.next(); 
    Map<String, Object> source = searchHit.getSource(); 
    if(source.get("district") != null){ 
     distinctObjects.put(source.get("district").toString(),source); 
    } 

} 
+0

Was ist, wenn Sie Paginierung verwenden? Erhalten Sie Seiten mit 8 Ergebnissen, andere mit 10 und andere mit 7, wenn Sie 10 Ergebnisse pro Seite erhalten? –

Verwandte Themen