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

Andreas
  • 154,647
  • 11
  • 152
  • 247
ESCoder
  • 15,431
  • 2
  • 19
  • 42
  • 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` https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.11/java-rest-high-search.html#java-rest-high-search-response – OranShuster Feb 10 '21 at 12:46
  • There are many JSON libraries, so please **always** specify which JSON library you are using, to help avoid confusion. – Andreas Feb 10 '21 at 12:51
  • @Andreas I am using Gson java library – ESCoder Feb 10 '21 at 13:12
  • @OranShuster I am using jest client of ES – ESCoder Feb 10 '21 at 13:15

1 Answers1

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());
Andreas
  • 154,647
  • 11
  • 152
  • 247