2013-01-22 15 views

risposta

18

È possibile creare un terms facet nel campo "full_name". Ma per farlo correttamente è necessario assicurarsi di non renderlo token durante l'indicizzazione, altrimenti ogni voce nel facet sarà un termine diverso che fa parte del contenuto del campo. Molto probabilmente dovrai configurarlo come "not_analyzed" nella tua mappatura. Se si sta effettuando una ricerca anche su di esso e si desidera comunque inizializzarlo, è possibile indicizzarlo in due modi diversi utilizzando multi field.

È inoltre necessario tenere conto del fatto che, in base al numero di termini univoci che fanno parte del campo full_name, questa operazione può essere costosa e richiedere un po 'di memoria.

12

Per elasticsearch 1.0 e versioni successive, è possibile sfruttare terms aggregation per fare questo,

interrogazione DSL:

{ 
    "aggs": { 
    "NAME": { 
     "terms": { 
     "field": "", 
     "size": 10 
     } 
    } 
    } 
} 

Un esempio reale:

{ 
    "aggs": { 
    "full_name": { 
     "terms": { 
     "field": "authors", 
     "size": 0 
     } 
    } 
    } 
} 

allora si può ottenere tutti i valori unici del campo authors. size = 0 significa non limitare il numero di termini (ciò richiede che es sia 1.1.0 o successivo).

Risposta:

{ 
    ... 

    "aggregations" : { 
     "full_name" : { 
      "buckets" : [ 
       { 
        "key" : "Ken", 
        "doc_count" : 10 
       }, 
       { 
        "key" : "Jim Gray", 
        "doc_count" : 10 
       }, 
      ] 
     } 
    } 
} 

vedere Elasticsearch terms aggregations.

+0

cosa vuol FULL_NAME significa? – neustart47

+2

@ neustart47 full_name è solo il nome delle aggregazioni –

4

Le risposte esistenti non ha funzionato per me in elasticsearch 5.x, per i seguenti motivi:

  • avevo bisogno di tokenize il mio ingresso, mentre l'indicizzazione.
  • "size": 0 Impossibile analizzare perché "[dimensione] deve essere maggiore di 0."
  • "Fielddata is disabled on text fields by default." Ciò significa che per impostazione predefinita non è possibile cercare nel campo full_name. Tuttavia, un campo non analizzato keyword può essere utilizzato per le aggregazioni.

Soluzione 1: utilizzare il Scroll API. Funziona mantenendo un contesto di ricerca e facendo richieste multiple, restituendo ogni volta successive serie di risultati. Se stai usando Python, il modulo elasticsearch ha lo scan() helper function per gestire lo scrolling per te e restituire tutti i risultati.

Soluzione 2: utilizzare Search After API. È simile a Scroll, ma fornisce un cursore live invece di mantenere un contesto di ricerca. Quindi è più efficiente per le richieste in tempo reale.

+0

Non sono sicuro che funzioni intorno alla "dimensione": 0 problema, perché l'impostazione predefinita per quanto posso vedere dai documenti è 10 ... – Trejkaz

+0

@Trejkaz Grazie; Ho aggiornato la mia risposta. –

0

Utilizzo per Elasticsearch 5.2.2

curl -XGET http://localhost:9200/articles/_search?pretty -d ' 
{ 
    "aggs" : { 
     "whatever" : { 
      "terms" : { "field" : "yourfield", "size":10000 } 
     } 
    }, 
    "size" : 0 
}' 

I "size":10000 mezzi ottengono (al massimo) 10000 valori univoci. Senza questo, se si hanno più di 10 valori univoci, vengono restituiti solo 10 valori.

Il "size":0 significa che, di conseguenza, "hits" non conterrà alcun documento. Di default, vengono restituiti 10 documenti, di cui non abbiamo bisogno.


Riferimento: bucket terms aggregation

noti inoltre, secondo this page, faccette sono state sostituite da aggregazioni di elasticsearch 1.0, che sono un insieme di sfaccettature.

0

Intuizione: In SQL gergo:

Select distinct full_name from authors;

è equivalente a

Select full_name from authors group by full_name;

Quindi, possiamo usare il raggruppamento/sintassi aggregato in elasticsearch per trovare le voci distinte .

Assumere il seguente è la struttura memorizzata in elasticsearch:

[{ 
    "author": "Brian Kernighan" 
    }, 
    { 
    "author": "Charles Dickens" 
    }] 

cosa non ha funzionato: Plain aggregazione

{ 
    "aggs": { 
    "full_name": { 
     "terms": { 
     "field": "author" 
     } 
    } 
    } 
} 

ho ottenuto il seguente errore:

{ 
    "error": { 
    "root_cause": [ 
     { 
     "reason": "Fielddata is disabled on text fields by default...", 
     "type": "illegal_argument_exception" 
     } 
    ] 
    } 
} 

Che cosa ha funzionato come un fascino: aggiungendo .keyword con il campo

{ 
    "aggs": { 
    "full_name": { 
     "terms": { 
     "field": "author.keyword" 
     } 
    } 
    } 
} 

E l'uscita di esempio potrebbe essere:

{ 
    "aggregations": { 
    "full_name": { 
     "buckets": [ 
     { 
      "doc_count": 372, 
      "key": "Charles Dickens" 
     }, 
     { 
      "doc_count": 283, 
      "key": "Brian Kernighan" 
     } 
     ], 
     "doc_count": 1000 
    } 
    } 
} 

Bonus suggerimento:

Assumiamo il campo in que Bustione è annidato come segue:

[{ 
    "authors": [{ 
     "details": [{ 
      "name": "Brian Kernighan" 
      }] 
     }] 
    }, 
    { 
    "authors": [{ 
     "details": [{ 
      "name": "Charles Dickens" 
      }] 
     }] 
    } 
] 

Ora la query giusta diventa:

{ 
    "aggregations": { 
    "full_name": { 
     "aggregations": { 
     "author_details": { 
      "terms": { 
      "field": "authors.details.name" 
      } 
     } 
     }, 
     "nested": { 
     "path": "authors.details" 
     } 
    } 
    }, 
    "size": 0 
} 
Problemi correlati