-1

サブセット ユーザーとして、2 つのドットを含むクエリを作成したいのですが、すぐには実行できません。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。フィールドの内容をシリアル化/逆シリアル化するためにサブセットTによって使用されますが、フィールドを含む単なるコンテナーですが、サブセットは、呼び出し時にそれを返します。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()Unitwherewhere

于 2013-03-01T09:20:41.603 に答える