1

I am trying to get the value of a key from the JsonArray. In result, I am getting the JsonObject, in the below format

{
  "docs": [
    {
      "_index": "esindex",
      "_type": "esmessage",
      "_id": "4",
      "_version": 1,
      "found": true,
      "_source": {
        "account_number": 4,
        "balance": 27658
      }
    }
  ]
}

I need to find the id of all those documents havig "found": true. The format of JsonArray produced is

[
  {
    "_index": "esindex",
    "_type": "esmessage",
    "_id": "4",
    "_version": 1,
    "found": true,
    "_source": {
      "account_number": 4,
      "balance": 27658
    }
  }
]

I am able to get the list of all the ids using the below java code

 List<Integer> documents = new ArrayList<>();
JsonObject result = esClient.execute(builder.build()).getJsonObject();
        JsonArray jsonArray = result.getAsJsonObject().get("docs").getAsJsonArray();
        while (i < request.getIds().size()) {
            JsonPrimitive checkIfExists = jsonArray.get(i).getAsJsonObject().getAsJsonPrimitive("found");
            if (checkIfExists.getAsString().equals("true"))
                documents.add(result.getAsJsonObject().get("docs").getAsJsonArray().get(i).getAsJsonObject().getAsJsonPrimitive("_id").getAsInt());
            i++;
        }

Can anyone please help me, to parse the JsonArray result using Java Stream API

4
  • 2
    May i ask why use streams to filter when you can use elasticsearch itself to get the relevant results? Assuming you are using the java rest client of ES, you can get a list of SearchHit objects from the response and then get the source of the document as a simple map elastic.co/guide/en/elasticsearch/client/java-rest/7.11/… Commented Feb 10, 2021 at 12:46
  • There are many JSON libraries, so please always specify which JSON library you are using, to help avoid confusion. Commented Feb 10, 2021 at 12:51
  • @Andreas I am using Gson java library Commented Feb 10, 2021 at 13:12
  • @OranShuster I am using jest client of ES Commented Feb 10, 2021 at 13:15

1 Answer 1

5

Realize that JsonArray is an Iterable<JsonElement>.

With that realization, you search and find "How to convert an iterator to a stream?", where you learn that you can use Spliterators.spliteratorUnknownSize() and StreamSupport.stream() to do this.

Stream<JsonElement> stream = StreamSupport.stream(
          Spliterators.spliteratorUnknownSize(jsonArray.iterator(),
                                              Spliterator.ORDERED),
          /*parallel*/false);

List<Integer> documents = stream.map(JsonElement::getAsJsonObject)
    .filter(o -> o.getAsJsonPrimitive("found").getAsBoolean())
    .map(o -> o.getAsJsonPrimitive("_id").getAsInt())
    .collect(Collectors.toList());

You of course know the size of the array, so you'll call Spliterators.spliterator() instead, and you can of course chain it all together:

List<Integer> documents = StreamSupport.stream(
          Spliterators.spliterator(jsonArray.iterator(),
                                   jsonArray.size(),
                                   Spliterator.ORDERED),
          /*parallel*/false)
    .map(JsonElement::getAsJsonObject)
    .filter(o -> o.getAsJsonPrimitive("found").getAsBoolean())
    .map(o -> o.getAsJsonPrimitive("_id").getAsInt())
    .collect(Collectors.toList());
Sign up to request clarification or add additional context in comments.

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.