2015-03-12 12 views
13

Devo rimuovere un campo in tutti i documenti indicizzati su Elasticsearch. Come posso farlo. Qualsiasi richiesta di eliminazione mi aiuterà a raggiungere questo obiettivo.Rimuovere un campo da un documento Elasticsearch

+0

Per impostazione predefinita non è possibile, perché in questo momento Lucene non supporta . Fondamentalmente è possibile solo inserire o rimuovere interi documenti Lucene dagli indici di Lucene .1 Ottieni la prima versione del tuo documento 2 rimuovi il campo 3 invia questa nuova versione del tuo documento. – Backtrack

risposta

18

Cosa @backtrack detto è vero, ma poi c'è un modo molto conveniente di farlo in Elasticsearch. Elasticsearch estrae la complessità interna della cancellazione. È necessario utilizzare l'aggiornamento API per raggiungere questo obiettivo -

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{ 
    "script" : "ctx._source.remove(\"name_of_field\")" 
}' 

È possibile trovare maggiori documentazione here.

Nota: A partire dal elasticsearch 6 si sono tenuti a includere un contenuto-tipo intestazione:

-H 'Content-Type: application/json' 
+0

Qual è la performance di questo se si dispone di un miliardo di documenti con questo campo? –

+0

Il documento effettivo verrà rimosso e ne verrà aggiunto uno nuovo per ciascuna di tali modifiche. –

+0

Avviso per ElasticSearch 5.0: è necessario utilizzare un parametro con nome anziché il nome con codice. I parametri sono più veloci e non interromperanno il limite di compilazione dello script. Vedi [documentazione] (https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html#prefer-params). –

7

Per impostazione predefinita non è possibile, perché in questo momento Lucene non lo supporta. Fondamentalmente puoi solo mettere o rimuovere interi documenti Lucene dagli indici di Lucene.

  1. ottenere la prima versione del documento
  2. rimuovere il campo
  3. spingere questa nuova versione del tuo documento
11

elasticsearch aggiunto update_by_query in 2.3. Questa interfaccia sperimentale consente di eseguire l'aggiornamento su tutti i documenti che corrispondono a una query.

Internamente elasticsearch esegue una scansione/scorrimento per raccogliere gruppi di documenti e quindi aggiornarli come l'interfaccia di aggiornamento di massa. Questo è più veloce rispetto a farlo manualmente con la propria interfaccia di scansione/scorrimento a causa di non avere il sovraccarico di rete e serializzazione. Ogni record deve essere caricato nella ram, modificato e quindi scritto.

Ieri ho rimosso un campo di grandi dimensioni dal mio cluster ES. Ho visto un throughput continuo di 10.000 record al secondo durante l'update_by_query, vincolato dalla CPU piuttosto che dall'IO.

Guardare in impostazione conflict=proceed se il cluster ha altro traffico di aggiornamento, o tutto il lavoro si ferma quando colpisce un ConflictError quando uno dei record viene aggiornato sotto uno dei lotti.

Analogamente modificando wait_for_completion=false causerà l'update_by_query eseguire tramite l'interfaccia tasks. Altrimenti il ​​lavoro terminerà se la connessione è chiusa.

url: corpo

http://localhost:9200/type/_update_by_query?wait_for_completion=false&conflict=proceed 

POST:

{ 
    "script": ctx._source.remove("name_of_field"), 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "exists": { 
      "field": "name_of_field" 
      } 
     } 
     ] 
    } 
    } 
} 

A partire dal elasticsearch 1,43, in linea groovy scripting is disabled by default. Dovrai abilitarlo affinché uno script in linea come questo funzioni aggiungendo script.inline: true al tuo file di configurazione.

Oppure caricare il groovy come script e utilizzare il formato "script": { "file": "scriptname", "lang": "groovy"}.

+0

Quello che non so ancora, è come recuperare lo spazio field_data utilizzato da quel campo. Sperando in un riavvio a rotazione, i numeri ordinali verranno ricaricati. – spazm

+1

Il corpo ha bisogno di una leggera modifica, ma per il resto funziona perfettamente. Ho dovuto avvolgere lo script in un oggetto JSON, probabilmente perché l'API è cambiata un po '. – Peter

Problemi correlati