0

我正在学习 Scala 并尝试使用 Mongo。我正在创建一个接收 aMap[String, Any]作为参数的函数,我想MongoDBObject为它返回正确的:

def parse(query: Map[String, Any]): MongoDBObject = {
  val result = query("operation") match {
    case "all" => query("field").toString $all query("value").asInstanceOf[List[String]]
    case "in" => query("field").toString $in query("value").asInstanceOf[List[String]]
    case "regex" => query("field").toString $regex query("value")
    case "eq" => query("field").toString $eq query("value")
    case "gt" => query("field").toString $gt query("value")
    case "gte" => query("field").toString $gte query("value")
    case "lt" => query("field").toString $lt query("value")
    case "lte" => query("field").toString $lte query("value")
    case "exists" => query("field").toString $exists query("value").asInstanceOf[Boolean]
    case "size" => query("field").toString $size query("value").asInstanceOf[Int]
    case "where" => $where(query("value").toString)
    case _ => throw new NotImplementedError("Unknown operation")
  }
}

我有一些问题。

  • 编译器说$regex不是String. 我不知道为什么。
  • 编译器说这Any不是一个有效的查询参数。我想我应该转换为 int、string、date 或任何其他有效的 Mongo 类型。有没有什么方法可以在没有反射的情况下解决这个问题来解决这个值的类型?
  • 对于$mod操作,我应该给出两个数值作为参数。我应该List为地图使用 as 值并获取第一个和第二个项目吗?
4

1 回答 1

1

它抱怨是$regex因为它没有在右侧找到可正则表达式的对象来应用用于解析$regex方法的转换——这也是您在以下所有调用中都会遇到的问题。

对于Any(以及$mod)的问题,我可以建议一种不同的方法吗?您没有类型信息Any,因此您无法真正绕过运行时强制转换(我也不确定反射将如何帮助您。)您不会以这种方式获得静态类型系统的任何好处。下面是一种方法的草图,您可以使用类型层次结构来实现这样的方法来强制类型安全:

sealed trait Query

case class All(field: String, value: List[String]) extends Query 
...
case class GreaterThan(field: String, value: Int) extends Query 
...
case class Mod(field: String, divisor: Int, remainder: Int) extends Query

def parse(q: Query): MongoDBObject = {
   q match {
      case All(f, v) => f $all v
      ...
      case GreaterThan(f, v) => f $gt v
      ...
      case Mod(f, d, r) => f $mod (d, r)
   }
}

或者,您可以在每个扩展类中定义一个抽象执行方法Query并覆盖它,而不是matchparse. 从那里,您可以使用类型参数或泛型类型进一步抽象,以允许例如GreaterThan采用任何Numeric类型。

于 2013-09-18T02:18:09.300 回答