1
 db.collectionB.findOne()
 {
    "_id" : NumberLong(24),
    "class" : "Top",
    "type" : DBRef("collectionA", NumberLong(47))
 }
db.collectionA.findOne()
{
   "_id" : NumberLong(47),
   "name" : "John",
   "position" : 2 
}

形成されるクエリ: db.collectionB.find({type: DBRef("collectionA", NumberLong(47))});

コレクション A とコレクション B には多数のドキュメントがあります。collectionB の type が collectionA の NumberLong(47) のドキュメントを参照しているドキュメントを検索したい。

BasicDBObject query =   new BasicDBObject("name","John");
DBObject db_object = findOne("collectionA",query);
DBRef myDbRef = new DBRef(db,"collectionB",db_object); 
DBObject doc = myDbRef.fetch(); 
System.out.println(doc);

出力は null になります。なんで?

4

1 に答える 1

4

DBRefの3 つの引数のコンストラクターは、次の引数を取ります。

  • データベース
  • 名前空間
  • ID

2 番目の引数は名前空間ではなく、単なるコレクションです。文字列である必要があります"yourDatabaseName.collectionB"

3 番目の引数は単なる ID ではなく、完全なオブジェクトです。そうすれば、DBRef は、フィールドの値が渡されたドキュメント_id の完全なコピーであるドキュメントを指します。そのようなドキュメントは存在しないため、DBRef を取得すると null が返されます。

有効な DBRef を作成するには、 の値_idを のコンストラクターに渡すだけですDBRef

しかし、「コレクションBの「タイプ」がコレクションAの「_id」がNumberLong(47)であるドキュメントを参照しているドキュメントを検索したい」という要件を理解したとき。正確には、collectionA に対してクエリを実行する必要さえありません。DBRef は、次の構造を持つ単なる透過的なサブオブジェクトです: { "$ref" : <value>, "$id" : <value>, "$db" : <value> }. したがって、次の方法で目的のドキュメントを見つけることができるはずです。

db.collectionB.find("type.$id": 47);

これは、すべての dbreftypeが同じコレクションとデータベースを参照していることを前提としています。そうでない場合は、結果が別のコレクションを参照するのを避けるために、これらをクエリに含める必要があります。

db.collectionB.find("type.$id": 47, "type.$ref": "collectionA", "type.$db": <database name>);
于 2013-10-11T11:46:57.870 に答える