How to get nested types in Elasticsearch

2019-08-06 15:57发布

问题:

I have the following document:

{
  "_index" : "testdb",
  "_type" : "artWork",
  "_id" : "0",
  "_version" : 4,
  "found" : true,
  "_source":{"uuid":0,
             "StatusHistoryList":[
        {
        "ArtWorkDate":"2015-08-28T15:52:03.030+05:00",
        "ArtworkStatus":"ACTIVE"
        },
        {
        "ArtWorkDate":"2015-08-28T15:52:03.030+05:00",
        "ArtworkStatus":"INACTIVE"
        }
             ]
}

and here is the mapping of the document:

{
  "testdb" : {
    "mappings" : {
      "artWork" : {
        "properties" : {
          "StatusHistoryList" : {
            "type" : "nested",
            "properties" : {
              "ArtWorkDate" : {
                "type" : "string",
                "store" : true
              },
              "ArtworkStatus" : {
                "type" : "string",
                "store" : true
              }
            }
          },

          "uuid" : {
            "type" : "integer",
            "store" : true
          }
        }
      }
    }
  }
}

Now I want to access the values of StatusHistoryList. I got null values if I do it like this:

val get = client.prepareGet("testdb", "artWork", Id.toString()).setOperationThreaded(false)
        .setFields("uuid",,"StatusHistoryList.ArtworkStatus","StatusHistoryList.ArtWorkDate","_source")

        .execute()
        .actionGet()
  var artworkStatusList= get.getField("StatusHistoryList.ArtworkStatus").getValues.toArray()

var artWorkDateList= get.getField("StatusHistoryList.ArtWorkDate").getValues.toArray()

then I got null values from the code but my document contains the values then I found this question so after that i tried to do it like this

 var smap = get.getSource.get("StatusHistoryList").asInstanceOf[Map[String,Object]]

but then a ClassCastException is thrown

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.util.Map

Please help me how can I get the values of StatusHistoryList 's ArtworkStatus and ArtWorkDate values please guide me I will be very thankfull to you.

回答1:

You have almost derived the solution. The GET request has retrieved the response but the problem is in parsing the response.

Let's see the problem. Below is the document that the elastic search returns as source

{
    "uuid":0,
    "StatusHistoryList":[
       {
          "ArtWorkDate":"2015-08-28T15:52:03.030+05:00",
          "ArtworkStatus":"ACTIVE"
       },
       {
          "ArtWorkDate":"2015-08-28T15:52:03.030+05:00",
          "ArtworkStatus":"INACTIVE"
       }
    ]
}

When we do get.getSource.get("StatusHistoryList") it returns List ArtWork objects and not a Map. That is the reason for the classCastException exception.

So if you cast the response to list of objects your problem will be solved.

But this would not be an ideal solution. Some of the libraries like Jackson-Faterxml does the job for you. Using the fasterxml library you can bind the json to equivalent POJO Object.