web-dev-qa-db-ja.com

MongoDB C#ドライバー2.4を使用したクエリにフィールドを含める/除外する

サーバーにドキュメントを含むコレクションがあります。各ドキュメントは次のようなものです。

{ _id: "...", Prop1: "", Prop2: "", Prop3: "", LargeField: "", ... }

他にも多くのフィールドがありますが、クライアントはこれらのフィールドを必要としません。

ドキュメントをMyDocクラスとしてロードしたいと思います。その定義は次のとおりです。

public class MyDoc {
    public string Id { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
    public string LargeField { get; set; }
}

私はもう試した:

var client = new MongoClient(uri);
var database = client.GetDatabase("MyDatabase");
var collection = database.GetCollection<MyDocs>("MyDocs");
var allDocs = collection.Find().ToList();

次に、各ドキュメントのすべてのフィールドが読み込まれるため、[BsonIgnoreExtraElements]MyDocに配置する必要があります。ここでの問題は、ドキュメントが大きいのに、フィールドのサブセットを制限するだけでよいということです。クラスで定義されたフィールドのみが必要であることをドライバーに知らせることはできますか?

そうでない場合は、LargeFieldなどの一部のフィールドを除外して、結果セットを小さくすることはできますか?私はもう試した:

var fieldsBuilder = Builders<MyDoc>.Projection;
var fields = fieldsBuilder.Exclude(d => d.LargeField);
var allDocs = collection.Find().Project(fields).ToList();

しかし、今ではallDocsBsonDocumentリストではなくMyDocリストになります。投影法でMyDocをクエリする方法は?

誰かが助けることができますか?従来のMongoDBドライバーではかなり単純ですが、新しいドライバーでそれを行う方法がわかりません。ありがとう。

7
Jeffrey Zhao

同様の問題が発生しました。何らかの理由でProjectが自動的にBsonDocumentを想定するため、ジェネリック型を指定する必要があると思います。これにより、BsonDocumentからクラスに修正されるはずです。

変化する:

var allDocs = collection.Find().Project(fields).ToList();

に:

var allDocs = collection.Find<MyDoc>().Project<MyDoc>(fields).ToList();

特定のフィールドのみを含める方法については、ビルダー(Includeを使用)または次のようなjson形式の文字列を使用して行うのと同じように行うことができます。

var allDocs = collection.Find<MyDoc>().Project<MyDoc>("{Prop1: 1, Prop2: 1}").ToList();

この男の投稿の投影をチェックすることを強くお勧めします: https://www.codementor.io/pmbanugo/working-with-mongodb-in-net-part-3-skip-sort-limit-and-予測-oqfwncyka

この記事から:

これにより、別の違いが生じます。プロジェクション定義を使用すると、ドキュメントタイプがStudentからBsonDocumentに暗黙的に変換されるため、返されるのは流暢なオブジェクトであり、結果としてBsonDocumentになります( Studentタイプです)。 Studentと連携する場合は、タイプをStudentに保持することを指定する必要があります。

8
Nate

新しい方法:

var fieldsBuilder = Builders<MyDoc>.Projection;
var fields = fieldsBuilder.Exclude(d => d.BigField1).Exclude(d => d.BigField2);

return Collection.Find(x => x.id.Equals(id)).Project<MyDoc>(fields).ToEnumerable();

ジーナ

1
Gina Marano