mapping elasticsearch inner hits result to class within java

610 Views Asked by At

I don't even know how to word this question properly so here's my best.

This is the result of me getting the innerhits from a nested field called "attributes" I have for an index (after filtering out the metadata):

"inner_hits" : {
 "attributes" : {
  "hits" : {
    "hits" : [
      {
         "_source" : {
         "name" : "Title",
         "value" : "title title"
         }
       },
       {
         "_source" : {
          "name" : "Author",
          "value" : "Test"
          }
        },
        {
          "_source" : {
          "name" : "Timestamp",
          "value" : "20.12.2022 11:06:03"
          }
         }
    ]
   }
  }
}

in other queries, I just return the whole document like such, so it's automatically mapped. In this case, the attributes are just automatically mapped to a List<AttributeClass> property within MyClass:

MyClass doc = null;

SearchResponse<MyClass> search = client
               .search(
                  s -> s
                     .index(myIndex)
                     .query(some-query),
                  MyClass.class);

List<Hit<MyClass>> hits = search.hits().hits();
for(Hit<MyClass> hit: hits) {doc = hit.source();}

return doc;

However, now that I'm trying to 'filter' things out with innerhits, the structure is a bit different. I have no idea how I can 'map' the inner hits list back to the original class now that it's a separate part outside of the hits.hits.source with its own source again. Is it better for me to just make a new json out of this? The result should be a readable json again.

Additional info: I'm using spring boot and ES 7.17.3

1

There are 1 best solutions below

0
Pompompurin On

My solution for future self and anyone that needs an idea. I don't think I went about the best way and I'm open to any more efficient ideas:

Due to some peculiar structures within my project I had to pack it within a Map to keep track of stuff as key-value pairs. I'll be sparing all the unrelated things

//imagine there's a SearchResponse called search here...
List<Hit<ClassForWholeResult>> hits = search.hits().hits();

for(Hit<ClassForWholeResult> hit: hits) {
  Pair<String, List<Hit<JsonData>>> firstPair = Pair
                  .of(firstPairKey, hit.innerHits().get(INNER_HIT_FIELD_NAME).hits().hits());
  
   //I had to insert my pairs into a map, I'm omitting it
}

//looping into the pairs that got inserted, pretend there's a loop for the map here
for(Pair<String, List<Hit<JsonData>>> pair: entryValue) {
   String pairKey = pair.getLeft();
   List<Hit<JsonData>> pairValue = pair.getRight();
   for(Hit<JsonData> innerhit: pairValue) {
       //I'm storing my results in a list
       storingList.add(innerhit.source().to(CORRESPONDING_CLASS.class));
}