我有以下型号
class Recording private() extends MongoRecord[Recording] with ObjectIdPk[Recording] {
def meta = Recording
object data extends StringField(this, 50)
}
我目前正在将“Json”对象保存为“data”字段中的字符串,我之前使用过JsonObject字段,但只使用了预定义的对象结构。在这种情况下,保存的json对象可以包含任何结构或数据字段,因此预定义的数据结构不是一个选项。
说我有:
{"name" : "James", "value" : "Hai!"}
或者
{"result" : 1, "handle" : "lorem_ipsum"}
我需要能够将两者都保存为同一字段中的json对象“data”。
我有办法做到这一点吗?
提前感谢您的帮助,非常感谢:)
答案 0 :(得分:0)
可能对您有用的是将数据存储为JValue
而不是String
。您可以使用JsonObjectField
包装一个包含JValue
的案例类,它允许任意结构,但它会在Mongo中为您提供额外的嵌套级别。要解决这个问题,如何创建自定义字段只是为了保留JValue
?
一次刺伤:
abstract class JValueObjectField[OwnerType <: BsonRecord[OwnerType]](rec: OwnerType)
extends Field[JValue,OwnerType]
with MandatoryTypedField[JValue]
with MongoFieldFlavor[JValue] {
def owner = rec
def defaultValue = JNothing
def toForm: Box[NodeSeq] = Empty
implicit val formats = owner.meta.formats
def asJValue: JValue = valueBox openOr JNothing
def setFromJValue(jv: JValue): Box[JValue] = Full(jv)
def setFromString(in: String): Box[JValue] = tryo(JsonParser.parse(in)) match {
case Full(jv: JValue) => setFromJValue(jv)
case f: Failure => setBox(f)
case other => setBox(Failure("Error parsing String into a JValue: "+in))
}
def setFromAny(in: Any): Box[JValue] = in match {
case dbo: DBObject => setFromDBObject(dbo)
case value: JValue => setBox(Full(value))
case Some(value: JValue) => setBox(Full(value))
case Full(value: JValue) => setBox(Full(value))
case (value: JValue) :: _ => setBox(Full(value))
case s: String => setFromString(s)
case Some(s: String) => setFromString(s)
case Full(s: String) => setFromString(s)
case null|None|Empty => setBox(defaultValueBox)
case f: Failure => setBox(f)
case o => setFromString(o.toString)
}
def asDBObject: DBObject = JObjectParser.parse(asJValue.asInstanceOf[JObject])
def setFromDBObject(dbo: DBObject): Box[JValue] =
setFromJValue(JObjectParser.serialize(dbo))
}
...看起来很多:我所做的就是从JValueObjectField
剪切并粘贴,删除了一个参数并修复为JValue
。可能有一种更聪明的方法可以做到这一点。
然后您可以在模型中使用它:
object data extends JValueObjectField(this)
我使用lift-json DSL填充它:
val json = ("name" -> "Bob") ~ ("result" -> 1)
Recording.createRecord.data(json).save
这将在MongoDB文档中为您提供如下内容:
"data" : {
"name" : "Bob",
"result" : 1
}
顺便说一下,Lift Mailing list是获得更好答案的好方法:恰好是与大多数与Lift有关的人聚集在一起的地方。
答案 1 :(得分:0)
class Recording private() extends MongoRecord[Recording] with ObjectIdPk[Recording] {
def meta = Recording
object data extends JObjectField(this)
}