6

と を使用してプロジェクトをセットアップしていplayframework 2.2.0ますplay2-reactivemongo 0.10.0-SNAPSHOT。次のような方法で、いくつかのドキュメントを ID でクエリしたいと思います。

def usersCollection = db.collection[JSONCollection]("users")
val ids: List[String] = /* fetched from somewhere else */
val query = ??
val users = usersCollection.find(query).cursor[User].collect[List]()

私が試したクエリとして:

Json.obj("_id" -> Json.obj("$in" -> ids))                        // 1
Json.obj("_id.$oid" -> Json.obj("$in" -> ids))                   // 2
Json.obj("_id" -> Json.obj("$oid" -> Json.obj("$in" -> ids)))    // 3

1 番目と 2 番目は空のリストを返し、3 番目はエラーで失敗しますassertion 10068 invalid operator: $oid

4

5 に答える 5

3

注: ReactiveMongo メーリング リストでの私の回答のコピー。

まず、私の回答が遅れて申し訳ありません、私はあなたの質問を見逃しているかもしれません. Play-ReactiveMongo は、Json 配列の値が ObjectIds であることを独自に推測することはできません。そのため、次のような ID ごとに Json オブジェクトを作成する必要があります{"$oid": "526fda0f9205b10c00c82e34"}。ReactiveMongo Play プラグインは、最初のフィールドが であるオブジェクトを検出すると$oid、それを ObjectId として扱い、ドライバーがこの値の正しいタイプを送信できるようにします (BSONObjectIDこの場合)。

これは実際にはより一般的な問題です。JSON 形式は BSON 形式と完全には一致しません。これは、数値型 ( BSONIntegerBSONLongBSONDouble)、BSONRegexBSONDateTime、およびの場合BSONObjectIDです。詳細については、MongoDB のドキュメント ( http://docs.mongodb.org/manual/reference/mongodb-extended-json/ ) を参照してください。

于 2013-11-11T12:34:36.403 に答える
0

私はそれを解決することができました:

val objectIds = ids.map(id => Json.obj("$oid" -> id))
val query = Json.obj("_id" -> Json.obj("$in" -> objectIds))
usersCollection.find(query).cursor[User].collect[List]()

play-reactivemongo 形式は、「$oid」の後に文字列が続く場合にのみ BSONObjectID を考慮するため

implicit object BSONObjectIDFormat extends PartialFormat[BSONObjectID] {
  def partialReads: PartialFunction[JsValue, JsResult[BSONObjectID]] = {
    case JsObject(("$oid", JsString(v)) +: Nil) => JsSuccess(BSONObjectID(v))
  }
  val partialWrites: PartialFunction[BSONValue, JsValue] = {
    case oid: BSONObjectID => Json.obj("$oid" -> oid.stringify)
  }
}

それでも、よりクリーンなソリューションがあることを願っています。そうでない場合は、素敵なプル リクエストになると思います。

于 2013-10-29T15:01:31.090 に答える
0

インポートplay.modules.reactivemongo.json._すると、$oid フォーマッターがなくても機能します。

import play.modules.reactivemongo.json._
...
val ids: Seq[BSONObjectID] = ???
val selector = Json.obj("_id" -> Json.obj("$in" -> ids))
usersCollection.find(selector).cursor[User].collect[Seq]()
于 2017-01-09T16:53:16.917 に答える
0

この方法で id を BSONObjectID に変換する方が安全ではないかどうか疑問に思っています。

val ids: List[String] = ???
val bsonObjectIds = ids.map(BSONObjectID.parse(_)).collect{case Success(t) => t}

これにより、有効な BSONObjectID のみが生成されます (無効なものは破棄されます)。

val objectIds = ids.map(id => Json.obj("$oid" -> id))

文字列 ID が実際に BSONObjectID の文字列化バージョンであるかどうかに応じて、objectIds は有効なものではない可能性があります。

于 2014-01-05T11:22:21.207 に答える