2013-08-30 4 views
1

스칼라 프로젝트의 MongoDB에서 문서를 올바르게 직렬화하는 방법을 알아 내려고하고 있습니다. 여기에있는 문제는 내 문서에 Array 필드가 있고 Scala에서이를 처리하는 방법을 알지 못합니다. 여기에 문서가 MongoDB의에서 어떻게 표시되는지를 보여줍니다 :Salat 및 Scala가 포함 된 임베디드 MongoDB Array에 대한 사례 클래스 만들기

> 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") 
} 
> 

지금 나는이 문서에 대한 사용자 지정 serializer를 생성하고 클라이언트에 제공 할 수 있도록 케이스 클래스를 작성해야합니다. 플레이어 해시가 문맥에 따라 다른 컬렉션 다를 수 있기 때문에

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 문서를 도출 할 수 있도록에서 어떻게해야합니까? Salat이 case 클래스에 serialize를 처리 할 수 ​​있다는 것을 알고 있습니다. 그러나 플레이어 특성을 처리하는 방법을 잘 모르겠습니다.

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 
    } 

} 

을 여기에 플레이어가 여기에지도를 맞게하는 방법을 아직 단서 I가 작동하기 시작했다 시리얼 라이저의 시작은하지만 위의 제안대로 선수지도는 포함되지 않지만 잘 작동합니다.

답변

0

배열은 지원되지 않습니다. 목록, seq, 거의 모든 다른 유형의 컬렉션으로 만들고 문서가 올바르게 serialize 및 deserialize됩니다.

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

는 모든 경우를 충당하기 위해 가능한 모든 필드와 사용의 기본 인수 플레이어 케이스 클래스를 확인합니다.

너무 많은 사례를 다루어야하는 경우, 상황이 실제로 추악 해집니다. 본질적으로 예상되는 구조가없는 데이터를 비 직렬화하려는 것은 ... 정확히 무엇입니까? 뛰어난 풀 요청이 있긴하지만 주류 Salat에 Map[String, Any] 지원을 추가하지 않았습니다.

+0

는 반드시지도 [문자열, 어떤] 작동하지 않습니다 있습니까 호출 할 수 있습니다? 나는 그것을 나의 케이스 클래스에 추가했다. 그리고 그것은 플레이어 배열을 움켜 잡고지도로 잘 돌리는 것처럼 보인다. 내 문제는 그 데이터를 표시하는 CustomSerializer를 사용하는 방법을 모르겠다. – randombits

0

당신은 아마 여기에 일부 사용자 지정 serializer를 사용해야합니다, 당신이 부모 개체에 대한 핸들이 가정은 - 그 부상

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