2011-11-05 2 views
27

Il mio test di integrazione/unità include test per la funzionalità di ricerca.Come cancellare l'indice ElasticSearch?

La mia idea è di avere un indice di ricerca vuoto prima di ogni test. Quindi, sto cercando di rimuovere tutti gli elementi di indice su setup metodo (è codice Groovy):

Client client = searchConnection.client 

SearchResponse response = client.prepareSearch("item") 
    .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) 
    .setQuery(termQuery('name', 'test')) //tried also matchAllQuery() 
    .setFrom(0).setSize(100).setExplain(false).execute().actionGet() 

List<String> ids = response.hits.hits.collect { 
    return it.id 
} 
client.close() 

client = searchConnection.client 

ids.each { 
    DeleteResponse delete = client.prepareDelete("item", "item", it) 
     .setOperationThreaded(false) 
     .execute().actionGet() 
} 

client.close() 

sembra che è l'elaborazione di tutte le eliminazioni in modo asincrono, così ho aggiunto Thread.sleep(5000) dopo di esso. Come vedi sto cercando di aprire/chiudere la connessione alcune volte - non aiuta lì. Il problema che a volte richiede più tempo, a volte occorrono più di 5 secondi per eliminarlo, a volte non riesce a trovare solo dati aggiunti (dal test precedente), ecc. Ecc. E il più fastidioso che i test di integrazione diventano instabili . Mettendo Thread.sleep() ovunque, dove è possibile, sembra una soluzione non così buona.

E c'è un modo per commettere ultime modifiche, o fare un blocco fino saranno scritti tutti i dati?

+0

Non è necessario chiamare a filo, basta chiamare l'API di aggiornamento per assicurarsi di poter cercare i dati più recenti indicizzati. – kimchy

risposta

34

soluzione trovata:

IndicesAdminClient adminClient = searchConnection.client.admin().indices(); 
String indexName = "location"; 
DeleteIndexResponse delete = adminClient.delete(new DeleteIndexRequest(indexName)).actionGet() 
if (!delete.isAcknowledged()) { 
    log.error("Index {} wasn't deleted", indexName); 
} 

e

client.admin().indices().flush(new FlushRequest('location')).actionGet(); 

dopo aver messo nuovi dati in indice.

+0

Grazie .. Quale biblioteca e come hai ottenuto una connessione? –

0

La mia idea è quella di avere indice di ricerca vuota prima di ogni prova

Quindi creare un nuovo indice all'inizio del test, non ri-utilizzare quello vecchio. Allora ti è garantito uno vuoto. Durante il teardown dei test, è possibile eliminare l'indice di test.

C'è un modo per confermare le ultime modifiche o bloccare finché tutti i dati non verranno scritti?

No, ElasticSearch non ha transazioni o blocchi.

Se non si desidera creare ogni volta un nuovo indice, provare ad aggiungere un ciclo che verifica se l'indice è vuoto, quindi attende e riprova, finché non lo è.

+0

Sì, è quello che sto cercando. Come posso creare un nuovo indice? –

+0

@splix: http://www.elasticsearch.org/guide/reference/api/admin-indices-create-index.html – skaffman

5
  1. non è la chiamata asincrona (è possibile aggiungere un ascoltatore ed evitare actionGet per ottenere la chiamata asincrona)
  2. eliminare tutti gli elementi tramite:

    client.prepareDeleteByQuery(indexName). 
          setQuery(QueryBuilders.matchAllQuery()). 
          setTypes(indexType). 
          execute().actionGet(); 
    
  3. aggiornare l'indice per vedere il modifiche (richiesto solo nei test unitari)

+2

i miei test hanno dimostrato che l'eliminazione di tutti gli articoli è più veloce rispetto alla creazione degli indici ... – Karussell

29

Prima di tutto non è necessario cancellare tutti i dati inviando un'eliminazione su ciascun ID doc. Puoi semplicemente cancellare tutti i dati eliminando per query tutti i documenti http://www.elasticsearch.org/guide/reference/api/delete-by-query.html Detto questo non lo consiglio, perché non è consigliabile farlo spesso su raccolte di documenti di grandi dimensioni (vedi documenti).

cosa si vuole veramente fare è cancellare l'intero indice (è veloce) http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-index.html, ricrearlo, messo nei dati e questo è importante aggiornare l'indice per "commit" le modifiche e renderli visibili. http://www.elasticsearch.org/guide/reference/api/admin-indices-refresh.html

Lo faccio nei test e non ho mai avuto problemi.

+8

Non c'è è necessario eseguire il flush, basta richiamare l'API di aggiornamento per accertarsi di cercare i dati più recenti. – kimchy

+0

Grazie kimchy, risolto in risposta! – johno

+0

I collegamenti non sono più disponibili. – vdolez