Search code examples
scalaorientdbdocument-database

OrientDB: How to get a list of children from an ODocument (in Scala)?


In Scala, if one has an ODocument object from querying an OrientDB database, how does one deserialize one of the document's fields that contains a list of child objects?

Consider the following (Scala) method that receives an ODocument and accesses the document's field "versions":

def document2package(doc: ODocument) = {
  val versions: String = doc.field("versions")
  // How to make versions into a Seq[Version]?
}

The "versions" field is actually a list of Version objects, but gets returned as a String. How do we deserialize this list?


Solution

  • Maybe you can just cast the result field as OTrackedList[*Something*] if you saved the document field as array. It seems to be automatically deserialized if *Something* implements OSerializableStream.

    The following code is the example that seems to work in Orient-DB 1.6.4.

    However if you inserted the "list of Version" as String when storing the document to db, then you might have to deserialize it to list by your own code.

    import com.orientechnologies.orient.core.record.impl.ODocument
    import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx
    import com.orientechnologies.orient.core.db.record.OTrackedList
    import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery
    import com.orientechnologies.orient.core.serialization.OSerializableStream
    import java.util.ArrayList
    import collection.JavaConverters._
    
    object Hoo{
      // To able to serialize/deserialize with OrientDB, you have to implement fromStream()/toStream()
      class Version(str:String) extends OSerializableStream{
        override def fromStream(stream:Array[Byte]):Version = {
          new Version(stream.map{_.toChar}.mkString(""))
        }
        override def toStream:Array[Byte] = {
          str.toArray.map{_.toByte}
        }
      }
    
      def main(args:Array[String]){
        // Open DB
        val db = new ODatabaseDocumentTx("local:/tmp/test")
        db.open("admin","admin")
        // Create Document
        val doc = new ODocument("Person")
        doc.field("versions",Array(new Version("3.1.4"),new Version("2.7.18")))
        // Save Document to DB
        doc.save
    
        // Query Doucument
        val result:ArrayList[ODocument] = db.query(new OSQLSynchQuery[ODocument]("select * from Person"))
        val lst:OTrackedList[Version] = result.get(0).field("versions")
        // OTrackedList is subclass of ArrayList, so you can convert it with toSeq()
        println(lst.asScala.toSeq) // prints Buffer(Main$Version|3.1.4, Main$Version|2.7.18)
      }
    }