3

While searching using java api in elaticsearch, I would like to retrieve only one column. Currently when I query using the Java API it returns the whole record like this: [{_id=123-456-7890, name=Wonder Woman, gender=FEMALE}, {_id=777-990-7890, name=Cat Woman, gender=FEMALE}]

The record above correctly matches the search condition shown in th . As shown in the code below:

        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();


        SearchRequestBuilder srb = client.prepareSearch("heros")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
        MatchQueryBuilder mqb;

        mqb = QueryBuilders.matchQuery("name", "Woman");
        srb.setQuery(mqb);
        SearchResponse response = srb.execute().actionGet();
        long totalHitCount = response.getHits().getTotalHits();

        System.out.println(response.getHits().getTotalHits());

        for (SearchHit hit : response.getHits()) {          
            result.add(hit.getSource());
        }

        System.out.println(result);

I want only one column to be returned. If I search for name I just want the full names back in a list: "Wonder Woman", "Cat Woman" only not the whole json record for each of them. If you think I need to iterate over the result list of maps in java please propose an example of how to do that in this case.

4 Answers 4

5

You can specify the fields to be returned from a search, per documentation. This can be set via SearchRequestBuilder.addFields(String... fields), ie:

    SearchRequestBuilder srb = client.prepareSearch("heros")
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .addFields("name");
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, it's addFields. Might be helpful to take a look at what is available.
5

Better combine both:

  • use .addFields("name") to tell ES that it needs to return only this column
  • use hit.field("name").getValue().toString() to get the result

It is important to use .addFields when you don't need the whole document, but the specific field/s as it will lower the overhead and the network traffic

3 Comments

Might I ask what the corresponding option is for Elasticsearch 5?
@MarkusBarthlen Did you found a solution to your question?
I believe I use .addStoredField and make sure the field is stored during indexing.
3

I figured it out.

    List<String> valuesList= new ArrayList<String>();
            for (SearchHit hit : response.getHits()) {                      
    result.add(hit.getSource());
    valuesList.add(hit.getSource().get("name").toString());         
}

Comments

0

The other solutions didn't work for me, hit.getSource() was returning null. Maybe they are deprecated? Not sure. But here was my solution, which FYI can speed things up considerably if you are only getting one field and you are getting lots of results.

Use addFields(Strings) on your SearchRequestBuilder as mentioned, but then when you are getting the values you need to use:

hit.getFields().get( fieldName ).getValue() or hit.getFields().get( fieldName ).getValues()

to get a single value or a list of values depending on the field.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.