2013-08-30 41 views
1

我想弄清楚如何在我的Scala項目中正確序列化來自MongoDB的文檔。我在這裏遇到的問題是當我在文檔中有一個Array字段以及如何在Scala中對待它時,我不知道該怎麼做。這裏的文件是什麼樣子MongoDB中:使用Salat和Scala爲嵌入式MongoDB數組創建案例類

> db.injuries.findOne() 
{ 
    "_id" : ObjectId("5220ef71bbf8af333d000001"), 
    "team_id" : 86, 
    "league" : "NFC", 
    "team_name" : "Arizona Cardinals", 
    "players" : [ 
     { 
      "player_id" : 9864, 
      "date" : "8/26/2013", 
      "position" : "TE", 
      "name" : "Rob Housler", 
      "injury" : "is doubtful for 9/8 against St. Louis", 
      "status" : "Doubtful", 
      "fantasy" : "", 
      "injured" : "True", 
      "type" : "ankle" 
     }, 
     { 
      "player_id" : 11610, 
      "date" : "8/25/2013", 
      "position" : "G", 
      "name" : "Jonathan Cooper", 
      "injury" : "may be placed on injured reserve", 
      "status" : "Out", 
      "fantasy" : "", 
      "injured" : "True", 
      "type" : "leg" 
     }, 
     { 
      "player_id" : 9126, 
      "date" : "4/3/2013", 
      "position" : "LB", 
      "name" : "Daryl Washington", 
      "injury" : "will be eligible to return on 10/6 against Carolina", 
      "status" : "Suspended", 
      "fantasy" : "", 
      "injured" : "True", 
      "type" : "four-game suspension" 
     } 
    ], 
    "updated_at" : ISODate("2013-08-30T19:16:01.466Z"), 
    "created_at" : ISODate("2013-08-30T19:16:01.466Z") 
} 
> 

現在我需要創建一個案例類,這樣我可以爲此文檔創建一個自定義序列,並將其交付給客戶。我開始建設的情況下,類像下面這樣:

case class Injury(_id: ObjectId = new ObjectId, team_id: Int, team_name: String, league: String, players: List[????], created_at: Option[Date] = None, updated_at: Option[Date] = None, id: Option[ObjectId] = None) 

我並不想創建一個播放器的情況下類,因爲球員哈希看在根據上下文其他收藏品不同。我可能會有一個玩家陣列來說一個「時間表」集合,我不打算在那裏列出傷病數據。這不是對玩家集合的實際引用,它只是一個帶有哈希的列表,其中的字段被命名爲「玩家」。理想情況下,我可以再弄清楚如何寫一個序列化會簡單的輸出這個當請求此團隊的ID:

{ 
    "team_id": 86, 
    "team_name": "Arizona Cardinals", 
    "players": [ 
    { 
     "player_id": 9864, 
     "date": "8/26/2013", 
     "position": "TE", 
     "name": "Rob Housler", 
     "injury": "is doubtful for 9/8 against St. Louis", 
     "status": "Doubtful", 
     "fantasy": "", 
     "injured": "True", 
     "type": "ankle" 
    }, 
    { 
     "player_id": 11610, 
     "date": "8/25/2013", 
     "position": "G", 
     "name": "Jonathan Cooper", 
     "injury": "may be placed on injured reserve", 
     "status": "Out", 
     "fantasy": "", 
     "injured": "True", 
     "type": "leg" 
    }, 
    { 
     "player_id": 9126, 
     "date": "4/3/2013", 
     "position": "LB", 
     "name": "Daryl Washington", 
     "injury": "will be eligible to return on 10/6 against Carolina", 
     "status": "Suspended", 
     "fantasy": "", 
     "injured": "True", 
     "type": "four-game suspension" 
    } 
    ] 
} 

還有什麼我必須爲了能夠衍生到最後JSON文件怎麼辦?我知道薩拉特可以處理序列化到案例類,但我不知道如何處理這裏的球員屬性。這裏有一個串行我開始工作的開始,但仍然毫無頭緒如何適應玩家映射到這裏:

class InjurySerializer extends CustomSerializer[Injury](format => ({ 
    case JObject(
    ("id", JString(id)) :: 
    ("team_id", JString(team_id)) :: 
    ("team_name" , JString(team_name)) :: 
    ("league" , JString(league)) :: Nil) => 
    Injury(new ObjectId, team_id.asInstanceOf[Int], team_name.asInstanceOf[String], league.asInstanceOf[String]) 
}, { 
    case injury: Injury => 
    JObject.apply(
     "team_id" -> JInt(injury.team_id), 
     "team_name" -> JString(injury.team_name), 
     "league" -> JString(injury.league) 
    ) 
})) 

然後,我有一個簡單的輔助檢索所有文件:

object Injury { 

    def findAll = { 
    val results = InjuryDAO.findAll 
    results.map(grater[Injury].asObject(_)).toList 
    } 

} 

這工作正常,但不包括上面建議的球員地圖。

回答

0

不支持數組。使它成爲一個列表,一個seq,幾乎任何其他類型的集合,並且您的文檔將正確地序列化和反序列化。

https://github.com/novus/salat/wiki/Collections

請與所有可能的領域和使用默認參數的球員的情況下類涵蓋所有情況。

如果有太多不同的案例需要報道,那就是當事情變得非常醜陋。你基本上試圖反序列化沒有預期結構的數據......究竟是什麼?我沒有添加Map[String, Any]支持主流薩拉特,雖然有一個出色的拉請求。

+0

確定地圖[字符串,任何]將無法正常工作?我在我的課堂課上添加了這個功能,它似乎在抓住玩家陣列,並將它變成一張Map就好了。我的問題是我不知道如何使用CustomSerializer來顯示這些數據。 – randombits

0

你可能要在這裏使用了一些自定義序列化,我假設你有一個句柄父對象 - 允許調用傷害

val playerRefs = injury.get("palyers") 
var obj = MongoDBObject("list" -> playerRefs) 
obj.as[MongoDBList]("list").toList.foreach { 
    value => 
     val playerDef = value.asInstanceOf[BasicDBObject] 
     // Access values from player - 
     val name = playerDef.get("name")asInstanceOf[String] 
     // Build your case class 
    } 
+0

我並不確定如何將其嵌入到我的序列化中。我將繼續並在上面發佈我的序列化程序的開始。 – randombits