1

ネイティブの Elasticsearch Java API に問題があります。名前属性でオブジェクトを検索するメソッドを作成したかったのです。ここまでは簡単でした。その後、このメソッドの JUnit テストを作成したいと思いました。ここから問題が始まります。

    @Test
public void nameSearchTest() throws ElasticSearchUnavailableException, IOException{
    String nameToSearch = "fuzzyText";
    TrainingToCreate t = new TrainingToCreate();
    t.setName(nameToSearch);
    //Create two Trainings to find sth
    String id1 = ElasticIndexer.index(t);
    String id2 = ElasticIndexer.index(t);
    //For creating delay, throws Exception if id doesn't exist
    ElasticGetter.getTrainingById(id1);
    ElasticGetter.getTrainingById(id2);

    int hits = 0;
    ArrayList<Training> trainings = ElasticSearch.fuzzySearchTrainingByName(nameToSearch, Integer.MAX_VALUE, 0);
    System.out.println("First id: " + id1);
    System.out.println("Second id: " + id2);
    String idOfTraining;
    if(trainings.size() == 0){
        System.out.println("Zero hits could be found.");
    }
    //just for printing id's of results
    //-------------------------------------------------
    for (int i = 0; i < trainings.size(); i++) {
        idOfTraining = trainings.get(i).getId();
        System.out.println("Training: "+i+" id: "+ idOfTraining);
    }
    //-------------------------------------------------
    for (Training training : trainings) {
        if(training.getId().equals(id1)||training.getId().equals(id2)){
            hits++;
        }
    }
    assertTrue(hits>=2);
    ElasticDelete.deleteTrainingById(id1);
    ElasticDelete.deleteTrainingById(id2);
}

このテストが問題なく機能する場合もあれば、何かが見つかることを確認するためにいくつかのドキュメントを作成したとしても、検索結果に何も含まれない場合もあります。しかし、elasticsearch のデータベースを見ると、ドキュメントが存在するので、実装が正しくないか、検索 API に深刻な遅延があると思います。

テストされているコードは次のとおりです。

public static ArrayList<Training> fuzzySearchTrainingByName(String name, int size, int offset) throws ElasticSearchUnavailableException, JsonParseException, JsonMappingException, IOException {
    Client client = clientFactory.getClient(configService.getConfig().getElasticSearchIp(), configService
            .getConfig().getElasticSearchPort());
    return ElasticSearch.fuzzySearchDocument(client, "trainings", "training", "name", name, size, offset);
}

private static ArrayList<Training> fuzzySearchDocument(Client client, String index, String type, String field, String value, int size, int offset) throws JsonParseException, JsonMappingException, IOException {
    QueryBuilder query = fuzzyQuery(field, value);

    SearchResponse response = client.prepareSearch(index).setTypes(type)
            .setQuery(query).setSize(size).setFrom(offset).execute().actionGet();

    SearchHits hits = response.getHits();

    TrainingToCreate source = null;
    ObjectMapper mapper = new ObjectMapper();
    ArrayList<Training> trainings = new ArrayList<Training>();

    for (SearchHit searchHit : hits) {
        source = mapper.readValue(searchHit.getSourceAsString(), TrainingToCreate.class);
        trainings.add(TrainingFactory.getTraining(searchHit.getId(), source));
    }
    return trainings;

}

Elastic 1.7.0 を使用して Java 8 で作業しています。問題の位置を特定できる人はいますか? さらに詳しい情報が必要な場合は、お気軽にお問い合わせください。

4

1 に答える 1

0

Elasticsearch はほぼリアルタイムです。つまり、ドキュメントのインデックスを作成してから検索可能になるまでの間に、ある程度の遅延 (デフォルトでは 1 秒) があります。これは、クエリを実行する前にインデックスを更新するだけで解決できます。

したがって、サンプルドキュメントのインデックスを作成した直後にそれを行います...

public void nameSearchTest() throws ElasticSearchUnavailableException, IOException{
    String nameToSearch = "fuzzyText";
    TrainingToCreate t = new TrainingToCreate();
    t.setName(nameToSearch);
    //Create two Trainings to find sth
    String id1 = ElasticIndexer.index(t);
    String id2 = ElasticIndexer.index(t);

    // REFRESH YOUR INDICES (just after indexing)
    client().admin().indices().prepareRefresh().execute().actionGet();

...またはちょうど最初にfuzzySearchDocument

 private static ArrayList<Training> fuzzySearchDocument(Client client, String index, String type, String field, String value, int size, int offset) throws JsonParseException, JsonMappingException, IOException {
     // REFRESH YOUR INDICES (just before searching)
     client().admin().indices().prepareRefresh().execute().actionGet();

     QueryBuilder query = fuzzyQuery(field, value);
     ...

サンプル ドキュメントでいくつかのテスト ケースを実行する場合は、最初のオプションを使用します。それ以外の場合は、どのオプションでも構いません。

于 2015-10-01T02:46:14.373 に答える