2

公式のC#ドライバーバージョン1.7を介して、MongoDBコレクションに(配列内の)埋め込みドキュメントをクエリする方法を知りたいですか?埋め込まれたドキュメントをクエリするということは、埋め込まれたドキュメントのみを取得し、それを含むドキュメント、別名プロジェクションは取得したくないということです。

ドキュメントが埋め込まれたデータモデルの種類の例、私はクエリを実行しています:

// Library, contained in db.Libraries
{
    _id: 1,
    Categories: [{_id: 2, Name: "Classics", Books: [{_id: 3, Name: The Count of Monte Cristo}]}]
}

ここでの問題は、1のオブジェクトと3_idの本の1つをライブラリコレクションに照会し_id、本のみを返す方法です。それはまったく実行可能ですか?私の知る限り、MongoDBシェルのプロジェクションを介してこれを行うことは可能です。

_id私のクエリ例は、db.Librariesに、1のライブラリに含まれる3の本をクエリすること_idです。返される本は次のサブドキュメントになります。

{_id: 3, Name: The Count of Monte Cristo}]}

MongoDBの公式C#ドライバーを使用して埋め込みドキュメントを取得するにはどうすればよいですか?、しかし私は受け入れられた答えを私のために働かせることができません。

編集:

MongoDBの公式C#ドライバーを使用して埋め込みドキュメントを取得する方法の受け入れられた答えがわかりましたか?作品、一種。見つかった各ドキュメントを繰り返し処理することを確認できませんでした。これは次のようになります。

var libraryCollection = new MongoCollection<Library>();
var refBook = new Book { Id = ObjectId.GenerateNewId().ToString(), Name = "The Count of Monte Cristo" };
libraryCollection.Insert(new Library { Id = ObjectId.GenerateNewId().ToString(), Categories = new[] { new Category { Books = new[] { refBook } } } });

MongoCursor<Library> libraries = libraryCollection.Find(new QueryDocument(
                    new Dictionary<string, object>
                        {
                            {"_id", new ObjectId()},
                        }
                    ));
Book book;
foreach (var library in libraries)
{
    book = library.Categories.SelectMany(c => c.Books).FirstOrDefault(b => b.Id == refBook.Id);
}

ただし、このソリューションは、埋め込まれたBookドキュメントだけでなく、Libraryドキュメント全体を取得するため、意味がありません。私は本当に、埋め込まれた本、別名プロジェクションだけを逆シリアル化する必要があった後です。

4

1 に答える 1

4

結果のドキュメントがフィルタリングされるだけでなく、再形成される投影を実行するには、次のようなメソッドAggregateのいずれかの代わりに使用する必要があります。Find

var result = collection.Aggregate(
    // Only include the document where _id = 1
    new BsonDocument {{"$match", new BsonDocument {{"_id", 1}}}},
    // 'Unwind' the Categories array by duplicating the docs, one per element.
    new BsonDocument {{"$unwind", "$Categories"}},
    // Now do the same for the Books array inside each Categories element.
    new BsonDocument {{"$unwind", "$Categories.Books"}},
    // Only include the resulting docs with a Book _id of 3
    new BsonDocument {{"$match", new BsonDocument {{"Categories.Books._id", 3}}}},
    // Reshape the document to bring the book attributes out to the top level 
    new BsonDocument {{"$project", new BsonDocument {
        {"_id", "$Categories.Books._id"},
        {"Name", "$Categories.Books.Name"}
    }}}
);

result.Response.toJson():

{"result": [{ "_id": 3.0, "Name": "The Count of Monte Cristo" }], "ok": 1.0 }
于 2013-01-26T22:23:52.763 に答える