【问题标题】:How to use lift-json's class extractor constructor mongo bson array?如何使用 lift-json 类提取器构造函数 mongodb bson 数组?
【发布时间】:2016-03-22 09:37:14
【问题描述】:

我使用 lift-json 渲染一个带有类提取器的 bson 字符串,之后,使用 mongo Document 类构造函数带有该 bson 字符串的文档实例。

一个问题是如何表示$or bson。它似乎不是一个经典的json数组。

 {"$or": [
      {"username": "administrator"},
      {"phone":"110"},
      {"email":"123@xxx.com"},
      {"pen_name":"lorancechen"}
 ]}

如何使用提升类提取器来表示这个 bson 数组?

另外,app和mongo之间使用string的原因是它们是在一个简单的socket下进行通信的。

更新添加示例
提取一个普通的数组类如下:

import net.liftweb.json._
import net.liftweb.json.Extraction._

case class Name(name: String)
case class JsonArray(array:List[Name])

object JsonClient extends App {
  implicit val formats = DefaultFormats

  val names = Name("jone01") :: Name("jone02") :: Nil
  val array = JsonArray(names)
  val jsonString = prettyRender(decompose(array))
  println(jsonString)
}

输出:

{
  "array":[
    {
      "name":"jone01"
    },
    {
      "name":"jone02"
    }
  ]
}

如何表示这个

{"$or": [
      {"username": "administrator"},
      {"phone":"110"},
      {"email":"123@xxx.com"},
      {"pen_name":"lorancechen"}
 ]}

元素内部“$or”的每个字段键(例如,usernamephone)不是通用键名,我还没有找到使用类模板来表示它的方法。

【问题讨论】:

  • 为什么你认为这不是一个正常的数组?文档不是数组。您是在问如何将所有文档键表示为数组中的单个元素?
  • @BlakesSeven,我添加了一个例子。我想它会直接表达我的奇迹。
  • 没有自己实际测试代码,你是说输出实际上包含名为array的键吗?即便如此,JsonArray(names) 的输出不会直接作为$or 的输入(它使用文档数组)。这似乎是最直接的用法。
  • @BlakesSeven,不是$or,换句话说,我想知道的是如何使用类构造函数输出$or的数组内部。因为数组字段的key(username,phone,etc)是不同的,例子不能用它的方式来表示。
  • 这是我在第一条评论中所说的。如果您序列化您的课程,您基本上会得到{ "username": "administrator", "phone": "110" },并且您想制作[ { "username": "administrator" }, { "phone": "110" }] 对吗?

标签: mongodb lift


【解决方案1】:

我不明白为什么你的 JSON 结构是这样的,也许你想要的是下面的:

{
  "$or": [
    {
      "username": "administrator", "phone":"110",  
      "email":"123@xxx.com", "pen_name":"lorancechen"
    },
    {
      "username": "xxx", "phone":"xxx",  
      "email":"xxx", "pen_name":"xxx"
    }
    ...
  ]
}

实际上Lift提供了这样的工具,缺点是实现有点难看。

  import net.liftweb.mongodb.{JsonObjectMeta, JsonObject}

  // the trait here is for unifying the type of 
  //four case classes i.e Username, Phone....
  sealed trait PersonField

  object Username extends JsonObjectMeta[Username]
  case class Username(username: String) extends JsonObject[Username] 
     with PersonField {
     def meta = Username
  }

  case class Phone(phone: String) extends JsonObject[Phone] with PersonField {
     def meta = Phone
  }
  object Phone extends JsonObjectMeta[Phone]

  case class Email(email: String) extends JsonObject[Email] with PersonField {
     def meta = Email
  }
  object Email extends JsonObjectMeta[Email]

  case class PenName(pen_name: String) extends JsonObject[PenName] 
     with PersonField {
     def meta = PenName
  }
  object PenName extends JsonObjectMeta[PenName]

  case class Output(`$or`: List[PersonField]) extends JsonObject[Output] {
    def meta = Output
  }

  object Output extends JsonObjectMeta[Output]


  object JsonClient extends App {

     val username = Username("administrator")
     val phone = Phone("110")
     val email = Email("123@xxx.com")
     val penName = PenName("lorancechen")
     val outPut = Output(username :: phone :: email :: penName :: Nil)

     import net.liftweb.json._
     implicit val formats = DefaultFormats

     import net.liftweb.json.{JsonAST, Printer}
     val result = Printer.pretty(JsonAST.render(outPut.asJObject))

     /*
        {
          "$or":[{
            "username":"administrator"
          },{
            "phone":"110"
          },{
            "email":"123@xxx.com"
          },{
            "pen_name":"lorancechen"
          }]
        }

     */
     println(result)
  }

不管怎样,希望对你有帮助。

【讨论】:

  • 谢谢,艾伦。虽然我还没有准备好为 Json 结构构建一个 mongo 模块,但它与这些类配合得很好。 :-)
猜你喜欢
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2017-06-04
  • 2022-12-20
  • 1970-01-01
  • 2018-10-02
  • 2013-03-03
  • 1970-01-01
相关资源
最近更新 更多