web-dev-qa-db-ja.com

C#.NETドライバー2.0を使用したmongodbサブドキュメントの投影

私は次の構造を持っています:

public class Category
{
    [BsonElement("name")]
    public string CategoryName { get; set; }

    [BsonDateTimeOptions]
    [BsonElement("dateCreated")]
    public DateTime DateStamp { get; set; }

    [BsonElement("tasks")]        
    public List<TaskTracker.Task> Task { get; set; }
}

public class Task
{
    [BsonElement("name")]
    public string TaskName { get; set; }

    [BsonElement("body")]
    public string TaskBody { get; set; }
}

CategoryをクエリしてすべてのTaskName値を取得し、それらをリストに戻してリストボックスに表示しようとしています。

私はこのクエリを使用してみました:

var getTasks = Categories.Find<Category>(x => x.CategoryName == catName)
                         .Project(Builders<Category>.Projection
                                                    .Include("tasks.name")
                                                    .Exclude("_id"))
                         .ToListAsync()
                         .Result;   

しかし、返されるのは:{"tasks": [{"name: "test"}]}

とにかく文字列値を返すだけですか?

10
Lynchy

Avishが言ったように、結果のドキュメントを希望どおりに表示するには、集計APIを使用する必要があります。ただし、Findの場合と同じようにプロジェクトに式ツリーAPIを使用すると、ドライバーによってこれらの一部が表示されなくなる可能性があります。たとえば、私は次のことがうまくいくと思います:

var taskNames = await Categores.Find(x => x.CategoryName == catName)
    .Project(x => x.Tasks.Select(y => y.Name))
    .ToListAsync();

これは、列挙可能な文字列(tasks.name)各カテゴリ。ドライバーはこのプロジェクションを検査し、tasks.nameフィールド。

17
Craig Wilson

MongoDBは、SQLデータベースのように実際にプロジェクションをサポートしていません。部分的なドキュメントを要求することはできますが、クエリを実行したドキュメントのスキーマに一致するものは返されます。あなたのケースでは、tasksフィールドのみが返され、タスクごとにnameフィールドのみが返されます。

プレーンなLINQを使用して、これを文字列のリストに簡単に変換できます。

var categoryTasks = Categories.Find<Category>(x => x.CategoryName == catName)
                     .Project(Builders<Category>.Projection
                                                .Include("tasks.name")
                                                .Exclude("_id"))
                     .ToListAsync()
                     .Result;   

var taskNames = categoryTasks.Tasks.Select(task => task.Name).ToList();

または、集計API(ちょっとしたカスタムプロジェクションをサポートしています)を使っていくつかの特別なことを行うこともできますが、それはおそらくあなたにとってはやり過ぎでしょう。

6
Avish