有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法让findAll在Elasticsearch中工作

我使用以下代码在Elasticsearch中创建文档:

    public static final String INDEX = "profile";

    private RestHighLevelClient client;

    ...

    public DocWriteResponse.Result createProfileDocument(ProfileDocument document)
            throws Exception
    {
        UUID uuid = UUID.randomUUID();
        document.setId(uuid.toString());

        IndexRequest indexRequest = new IndexRequest(INDEX);
        indexRequest.id(document.getId());
        indexRequest.source(document, XContentType.JSON);
        indexRequest.opType("create");

        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);

        return indexResponse.getResult();
    }

我想对所有条目执行一个简单的搜索。我有以下代码:

    public List<ProfileDocument> findAll()
            throws Exception
    {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());

        SearchRequest searchRequest = buildSearchRequest(INDEX);
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        return getSearchResult(searchResponse);
    }

    private List<ProfileDocument> getSearchResult(SearchResponse response)
    {
        SearchHit[] searchHit = response.getHits().getHits();

        List<ProfileDocument> profileDocuments = new ArrayList<>();

        for (SearchHit hit : searchHit)
        {
            profileDocuments.add(objectMapper.convertValue(hit.getSourceAsMap(), ProfileDocument.class));
        }

        return profileDocuments;
    }

    private SearchRequest buildSearchRequest(String index)
    {
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices(index);

        return searchRequest;
    }


这是ProfileDocument的代码:

public class ProfileDocument
{

    private String id;

    private String name;


    public ProfileDocument()
    {
    }

    public ProfileDocument(String id, String name)
    {
        this.id = id;
        this.name = name;
    }

    public String getId()
    {
        return id;
    }

    public void setId(String id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    @Override
    public String toString()
    {
        return id + ":" + name;
    }

}

当我执行:

import ...

@SpringBootTest(classes = Application.class)
@ActiveProfiles(profiles = "test")
public class ProfileServiceTest
{

    @Inject
    private ProfileService profileService;


    @Test
    public void testCRUD()
            throws Exception
    {
        ProfileDocument document = new ProfileDocument("foo", "bar");

        DocWriteResponse.Result result = profileService.createProfileDocument(document);

        assertEquals(DocWriteResponse.Result.CREATED,
                     result,
                     "Failed to store the test document!");

        // This actually prints CREATED
        System.out.println();
        System.out.println();
        System.out.println(result.name());
        System.out.println();
        System.out.println();

        List<ProfileDocument> profileDocuments = profileService.findAll();

        assertNotNull(profileDocuments, "Failed to find any results!");
        // It fails here:
        assertFalse(profileDocuments.isEmpty(), "Failed to find any results!");

        for (ProfileDocument profileDocument : profileDocuments)
        {
            System.out.println(profileDocument.toString());
        }

        ProfileDocument byId = profileService.findById("foo");

        System.out.println(byId.toString());

        assertNotNull(byId, "Failed to find the document by an ID!");

        List<ProfileDocument> byNames = profileService.findProfileByName("bar");

        assertFalse(byNames.isEmpty(), "Failed to find the document by a name!");
    }

}

我不明白为什么它说它创建了文档,但是findAll部分不起作用,它返回一个空对象,如下所示:

00:48:33.344 26-09-2019 | INFO  | main                 | c.e.aws.elasticsearch.demo.ProfileServiceTest      | Starting ProfileServiceTest on carlspring with PID 6598 (started by carlspring in /java/opensource/examples/spring-boot-java-highlevel-rest-client-elasticsearch)
00:48:33.345 26-09-2019 | INFO  | main                 | c.e.aws.elasticsearch.demo.ProfileServiceTest      | The following profiles are active: test
00:48:35.485 26-09-2019 | INFO  | main                 | c.e.aws.elasticsearch.demo.ProfileServiceTest      | Started ProfileServiceTest in 3.09 seconds (JVM running for 4.065)
[2019-09-26T00:48:40,919][INFO ][o.e.c.m.MetaDataCreateIndexService] [carlspring] [profile] creating index, cause [auto(bulk api)], templates [], shards [1]/[1], mappings []
[2019-09-26T00:48:41,461][INFO ][o.e.c.m.MetaDataMappingService] [carlspring] [profile/f3Egu6jWR9iJyYkVS-uVxw] create_mapping [_doc]


CREATED


null:null
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 10.396 s <<< FAILURE! - in com.example.aws.elasticsearch.demo.ProfileServiceTest
[ERROR] testCRUD  Time elapsed: 6.873 s  <<< ERROR!
java.lang.NullPointerException
    at com.example.aws.elasticsearch.demo.ProfileServiceTest.testCRUD(ProfileServiceTest.java:54)

[INFO] 
[INFO] Results:
[INFO] 
[ERROR] Errors: 
[ERROR]   ProfileServiceTest.testCRUD:54 NullPointer
[INFO] 
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0

我正在使用Elasticsearch 7.3.1

任何提示和帮助都将不胜感激


共 (1) 个答案

  1. # 1 楼答案

    这是因为在创建文档和搜索文档之间,索引尚未刷新

    您需要在createProfileDocument()中修改代码,如下所示:

        IndexRequest indexRequest = new IndexRequest(INDEX);
        indexRequest.id(document.getId());
        indexRequest.source(document, XContentType.JSON);
        indexRequest.opType("create");
    
        // add this line
        indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
    
        // assert: at this point the document will be searchable