web-dev-qa-db-ja.com

ElasticSearchインデックスを消去する方法は?

My nit/integration testsには検索機能のテストが含まれています。

私の考えは、各テストの前に空の検索インデックスを持つことです。だから、私はsetupメソッドのインデックス内のすべての要素を削除しようとしています(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()
_

すべての削除を非同期で処理しているようですので、その後にThread.sleep(5000)を追加しました。あなたが見るように、私は数回接続を開閉しようとしています-それはそこでは役に立ちません。

時間がかかる場合や、削除するのに5秒以上かかる場合、以前のテストで追加されたデータだけが見つからない場合などの問題があります。また、統合テストが不安定になることが最も厄介です。 Thread.sleep()を可能な場所に置くことは、あまり良い解決策ではないように見えます。

コミット最後の変更、またはすべてのデータが書き込まれるまでロックを行う方法はありますか?

28
Igor Artamonov

見つかった解決策:

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);
}

そして

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

新しいデータをインデックスに入れた後。

34
Igor Artamonov

まず、各ドキュメントIDで削除を発行してすべてのデータを消去する必要はありません。すべてのドキュメントに一致するクエリを使用して、deleteですべてのデータを削除できます http://www.elasticsearch.org/guide/reference/api/delete-by-query.html そうは言っていませんどちらかをお勧めします。大規模なドキュメントコレクションでこれを頻繁に行うことは推奨されないためです(ドキュメントを参照)。

本当にしたいことは、インデックス全体を削除することです(高速です) http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-index.html 、それを再作成します、データを入力し、これは重要ですインデックスを更新して変更を「コミット」し、それらを表示します。 http://www.elasticsearch.org/guide/reference/api/admin-indices-refresh.html

私はテストでこれを行いましたが、問題はありませんでした。

29
johno
  1. 非同期呼び出しではありません(リスナーを追加し、actionGetを回避して非同期呼び出しを取得できます)
  2. 以下を介してすべてのアイテムを削除します。

    client.prepareDeleteByQuery(indexName).
                setQuery(QueryBuilders.matchAllQuery()).
                setTypes(indexType).
                execute().actionGet();
    
  3. インデックスを更新して変更を確認します(単体テストでのみ必要)

5
Karussell

私のアイデアは、各テストの前に空の検索インデックスを持つことです

したがって、テストの開始時に新しいインデックスを作成し、古いインデックスを再利用しないでください。空の場合は保証されます。テストの分解で、テストインデックスを削除できます。

最後の変更をコミットする方法、またはすべてのデータが書き込まれるまでロックする方法はありますか?

いいえ、ElasticSearchにはトランザクションもロックもありません。

毎回新しいインデックスを作成したくない場合は、インデックスが空かどうかを確認するループを追加し、空になるまで待機して再試行します。

0
skaffman