0

I'm using elastic4s library to query elasticsearch (ES). Version of elastic4s and ES itself 2.4.0.

Suppose I have a compound object that I put to ES like

case class MyObject(id: Long, vall: KeyVal, vals: Seq[KeyVal])  

where KeyVal is

case class KeyVal(id: Long, name: String)  

Now I queried ES and got the response which I want to deserialiize back to MyObject:

implicit object MyObjectHitAs extends HitAs[MyObject] {
   override def as(hit: RichSearchHit): MyObject = {
     MyObject(
       hit.field("id").getValue[String]
       KeyVal(hit.field("vall.id").getValue[Long], field("vall.name").getValue[String]),
       //what should I code here to get the Seq[KeyVal] ???
     )
   }
 }

Please explain how can I deserialize the Array of KeyVal. Thank you.

evan.oman
  • 5,922
  • 22
  • 43
Alex
  • 62
  • 8

1 Answers1

1

In the more recent versions of elastic4s, ie 5.0 onwards, you would use the HitReader typeclass. Your example would then look like this.

 implicit object MyObjectHitAs extends HitReader[MyObject] {

    override def read(hit: Hit): Either[Throwable, MyObject] = {
      val obj = MyObject(
        hit.sourceField("id").toString.toLong,
        KeyVal(hit.sourceField("vall.id").toString.toLong, hit.sourceField("vall.name").toString),
        hit.sourceField("vals").asInstanceOf[Seq[AnyRef]].map { entry =>
          KeyVal(hit.sourceField("vall.id").toString.toLong, hit.sourceField("vall.name").toString)
        }
      )
      Right(obj)
    }
  }

Although it is a lot easier to use the built in json mappers than hand craft it.

sksamuel
  • 16,154
  • 8
  • 60
  • 108