2014-03-03 15 views
3

我需要將這個JSON遊戲框架:類型不匹配JsValue/JsValueWrapper

{ "matchItem": { "collection": { "fieldName": [ "value1", "value2" ] } } } 

轉換爲該MongoDB的投影:

{ "collection": { "$elemMatch": { "fieldName": "value1", "fieldName": "value2" } } 

這下面是我的代碼:

def toProjection(json: JsValue) = { 
    json.getOpt(__ \ "matchItem").map { value => 
    val obj = value.as[JsObject] 
    for (key <- obj.keys) { obj.getOpt(__ \ key).map { matchObj => 
     for (matchKey <- matchObj.as[JsObject].keys) { matchObj.getOpt(__ \ matchKey).map { items => 
     val fields = items.as[Seq[JsValue]].map(item => (matchKey -> item)) 
     seq += key -> Json.obj("$elemMatch" -> Json.obj(fields)) 
     }} 
    }} 
    } 
    if (seq.length > 0) JsObject(seq) else json 
} 

val json = """{ "matchItem": { "collection": { "fieldName": [ "value1", "value2" ] } } }""" 
val proj = toProjection(json) 

這代碼不編譯,我總是得到以下錯誤信息:

[error] /home/j3d/Projects/test/app/services/Test.scala:82: type mismatch; 
[error] found : Seq[(String, play.api.libs.json.JsValue)] 
[error] required: (String, play.api.libs.json.Json.JsValueWrapper) 
[error]     seq += fieldMaps.fromPublic(key) -> Json.obj("$elemMatch" -> Json.obj(fields)) 
[error]                      ^

我有點失落。我知道Json.obj是一個輔助的方法來建立JsObject實例:

JsObject(Seq(
    "key1" -> JsString("value1"), 
    "key2" -> JsString("value2") 
    ... 
)) 

...相當於:

Json.obj("key1" -> "value1", "key2" -> "value2") 

在上面我的代碼,該fields值是Seq[(String, play.api.libs.json.JsValue)] ...所以我不不明白爲什麼它不起作用。任何幫助將非常感激。

+0

我看到有一些關於JsValue和JsValueWrapper的討論[這裏](https://groups.google.com/forum/#!topic/play-framework/Bs5pEy2nAzs)可能會有所幫助。 – wwkudu

回答

4

這裏是解決方案:

def toProjection(json: JsValue) = { 
    json.getOpt(__ \ "matchItem").map { value => 
    val obj = value.as[JsObject] 
    for (key <- obj.keys) { obj.getOpt(__ \ key).map { matchObj => 
     for (matchKey <- matchObj.as[JsObject].keys) { matchObj.getOpt(__ \ matchKey).map { items => 
     val fields = items.as[Seq[JsValue]].map(item => (matchKey -> item)) 
    // seq += key -> Json.obj("$elemMatch" -> Json.obj(fields)) 
     seq += key -> Json.obj("$elemMatch" -> JsObject(fields)) 
     }} 
    }} 
    } 
    if (seq.length > 0) JsObject(seq) else json 
} 

更換Json.obj(fields)JsObject(fields)的伎倆。

我希望它有幫助。