Scala Generic MongoDB集合

时间:2017-03-31 10:25:59

标签: mongodb scala

mongo-scala-driver最近已更新,我想更新我的应用(link)以支持新添加的case classes

我目前在这些案例类中遇到问题而且找不到解决问题的方法(至少是正确的方法)。

我有一个名为Collection的特征,其中我定义了一些通用查询,而不是可以应用于我的任何集合:

import org.mongodb.scala.model.Filters._
import org.mongodb.scala.{MongoCollection, _}

import scala.concurrent.Future

trait Collection[T] {
  protected val DEFAULT_LIMIT_SIZE = 50
  protected val collection: MongoCollection[T]

  def insert(obj: String): Future[_]

  def get(id: Int) = collection.find(equal("_id", id)).first().head()

}

我还在子类中实现了一些特定于集合的查询,例如

import org.mongodb.scala.MongoCollection

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

object Groups extends Collection[Group] with Database {

  override val collection : MongoCollection[Group] =   database.withCodecRegistry(Group.codecRegistry).getCollection("groups")

  override def insert(groupId: String) : Future[Group] = {
    val group = Group(groupId.toLong)
    collection
      .insertOne(group)
      .head()
      .map(_ => group)
  }

  def all =
    collection
      .find()
      .toFuture()

}

问题来自get特征的Collection方法:

[error] Collection.scala:13: No ClassTag available for C
[error]   def get(id: Int) = collection.find(equal("_id", id)).first().head()

我很确定这是因为我使用trait类型参数作为MongoCollection的类型,但我不能想到另一种方法来实现它。

我怎么能实现这个目标?

由于

编辑:将(implicit ct: ClassTag[T])添加到Collection特征的每个方法中,它似乎有用,但我不是真的喜欢这样做......

EDIT2 :也可以将此implicit ct放入特征中,并从子类中覆盖它:

trait Collection[T] {
    implicit def ct: ClassTag[T]
    ...
}

在子类中:

object Groups extends Collection[Group] with Database {
    override def ct = implicitly
    ...
}

1 个答案:

答案 0 :(得分:0)

更新:您需要在收集特征的get方法中隐式传递ClassTag T

def get[T : scala.reflect.ClassTag] {
    //...........
}