Comment effacer L'index ElasticSearch?
Mon tests d'unité / d'intégration comprend des tests pour la fonctionnalité de recherche.
mon idée est d'avoir un index de recherche vide avant chaque test. Donc, j'essaie de supprimer tous les éléments dans index sur setup
méthode (c'est Groovy code):
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()
semble qu'il traite toutes les suppressions de façon asynchrone, donc j'ai ajouté Thread.sleep(5000)
d'après elle. Comme vous le voyez, j'essaie d'ouvrir/fermer la connexion plusieurs fois - cela n'aide pas là.
Le problème que parfois il demande plus de temps, parfois il a besoin de plus de 5 secondes pour supprimer, parfois il ne peut pas trouver juste des données ajoutées (du test précédent), etc, etc. Et le plus gênant, c'est que les tests d'intégration deviennent instables. Mettre Thread.sleep()
partout où il est possible semble pas si bonne solution.
C'est là un moyen de valider dernières modifications, ou faites un verrouillage jusqu'à ce que toutes les données seront écrites?
5 réponses
solution trouvée:
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);
}
et
client.admin().indices().flush(new FlushRequest('location')).actionGet();
après avoir mis de nouvelles données dans index.
tout d'abord, vous n'avez pas à effacer toutes les données en émettant une suppression sur chaque ID doc. Vous pouvez simplement supprimer toutes les données avec Supprimer par requête correspondant à tous les documents http://www.elasticsearch.org/guide/reference/api/delete-by-query.html Cela dit, Je ne recommande pas que non plus, parce qu'il n'est pas recommandé de le faire souvent sur de grandes collections de doc (voir docs).
ce que vous voulez vraiment faire c'est supprimer tout l'index (c'est rapide) http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-index.html , le recréer, mis en données et c'est important rafraîchir l'index pour "commit" les modifications et les rendre visibles. http://www.elasticsearch.org/guide/reference/api/admin-indices-refresh.html
je fais ça dans mes tests et je n'ai jamais eu de problème.
- ce n'est pas l'appel async (vous pouvez ajouter un écouteur et éviter actionGet pour obtenir l'appel async)
supprimer tous les éléments via:
client.prepareDeleteByQuery(indexName). setQuery(QueryBuilders.matchAllQuery()). setTypes(indexType). execute().actionGet();
rafraîchissez votre index pour voir les changements (seulement requis dans les tests unitaires)
mon idée est d'avoir un index de recherche vide avant chaque test
donc créer un nouvel index au début du test, ne pas réutiliser l'ancien. Vous avez la garantie d'un vide ensuite. Dans les tests de démontage, vous pouvez alors supprimer l'index de test.
y a-t-il un moyen de propager les dernières modifications, ou de verrouiller jusqu'à ce que toutes les données soient écrites?
Non, ElasticSearch n'a pas de transactions ou de verrouillage.
Si vous n'avez pas pour créer de nouveaux index à chaque fois, puis essayez d'ajouter une boucle qui vérifie si l'index est vide, puis attend et essaie de nouveau, jusqu'à ce qu'il est.
Vous pouvez également utiliser la commande curl pour supprimer l'index de recherche élastique
curl -XDELETE 'localhost:9200/index_name'