28

私のユニット/統合テストには、検索機能のテストが含まれています。

私の考えは、各テストの前に空の検索インデックスを用意することです。だから、私は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()可能な限りどこにでも置くことは、あまり良い解決策ではないように見えます。

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

4

4 に答える 4

33

見つかった解決策:

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

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

于 2012-06-04T05:10:45.523 に答える
30

まず、各ドキュメント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

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

于 2011-11-05T20:32:49.590 に答える
5
  1. 非同期呼び出しではありません(リスナーを追加して、actionGetを回避して非同期呼び出しを取得できます)
  2. 次の方法ですべてのアイテムを削除します。

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

于 2011-11-05T15:52:42.547 に答える
0

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

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

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

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

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

于 2011-11-05T10:11:34.053 に答える