-1

作为一个子集用户,我想生成一个包含两个点的查询,但我不能即时完成。让我增强您的 BlogPost 示例http://osinka.github.com/subset/Subset+Query.html来演示我想要实现的目标,即使这样没有意义:

case class SubComment(subText: String)
case class Comment(by: String, votes: Int, text: SubComment)
case class BlogPost(title: String, comments: List[Comment])
object SubComment {
    val text = "text".fieldOf[String]
    implicit val writer = {
      def f(sub: SubComment): DBObject = (text -> sub.subText)
      ValueWriter(f _)
    }
  }
  object Comment {
    val by = "by".fieldOf[String]
    val votes = "votes".fieldOf[Int]
    val text = "text".fieldOf[SubComment]
  }
  object BlogPost {
    val title = "title".fieldOf[String]
    val comments = "comments".subset(Comment).of[List[Comment]]
  }
  val qComment = BlogPost.comments.where { _.by === "maria" }
  val qSubComment = BlogPost.comments.where {…? === "X"} // not yet working

我怎样才能产生一个 DBObject { "comments.text.subText" : "X"}

谢谢,彼得

4

1 回答 1

1

我是Subset的作者,所以让我绕道而行并解释一下细节。

子集(1.x) 提供Field[T]向/从 MongoDB 文档 (BSON) 读取和/或写入字段。当您读取或写入该字段的内容时,它唯一必须知道的是T. 换句话说,如果您正在使用 BSON 文档,您可以将所有字段声明为"fieldName".fieldOf[T]任何复杂T的字段(例如列表或子文档)

一旦您需要创建查询,事情就会变得更加复杂。由于 MongoDB 支持“点表示法”,因此Subset需要知道父文档和后代字段之间的关系。当您将字段声明为"fieldName".subset(Obj).of[T]. 这里,T其实一点关系Obj都没有。SubsetT使用它来序列化/反序列化字段内容,而只是一个带有字段的容器,当您调用时,Subset会将其返回给您,例如Objwhere

让我通过例子来证明它。您需要在代码中更改的唯一内容如下:

object Comment {
  ...
  val text = "text".subset(SubComment).of[SubComment]
}

然后你会写

scala> val q = BlogPost.comments.where { comment =>
     | comment.text.where { _.text === "X" }
     | }
q: com.osinka.subset.package.Query = Query{ "comments.text.text" : "X"}

这里,comment Comment对象。


当您知道这一点时,您可以自由地“作弊”并执行以下操作:

val comments = "comments".subset(()).of[List[Comment]]
val commentText = "text".subset(()).of[SubComment]
val subcommentInnerField = "inner".fieldOf[String]

scala> comments.where { _ =>
     |   commentText.where { _ =>
     |     subcommentInnerField === "X"
     |   }
     | }
res1: com.osinka.subset.package.Query = Query{ "comments.text.inner" : "X"}

在这里,我正在给Unit方法.subset(),因此我们Unit又回到了where. 但这没关系,因为我们知道在where调用中使用哪些字段。这种“作弊”不像将字段保留在对象中那样“安全”,但很好地展示了事物的连接方式。

于 2013-03-01T09:20:41.603 回答