简体   繁体   English

使用C#.NET驱动程序2.0投影mongodb子文档

[英]Projection of mongodb subdocument using C# .NET driver 2.0

I have the following structure: 我有以下结构:

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; }
}

I am trying to query a Category to get all the TaskName values and then return them to a list to be displayed in a list box. 我试图查询Category以获取所有TaskName值,然后将它们返回到列表框中以显示。

I have tried using this query: 我试过使用这个查询:

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

But what get returned is: {"tasks": [{"name: "test"}]} . 但返回的是: {"tasks": [{"name: "test"}]}

Is there anyway to just return the string value? 无论如何只返回字符串值?

As Avish said, you have to use the aggregation API to get the resulting document to look like you are wanting. 正如Avish所说,您必须使用聚合API来使结果文档看起来像您想要的那样。 However, the driver can make some of that disappear for you if you use the expression tree API for project as you have done for Find. 但是,如果您使用表达式树API进行项目,则驱动程序可以使其中一些消失。 For instance, I believe the following should work for you: 例如,我相信以下内容适合您:

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

This should just bring back an enumerable of strings ( tasks.name ) for each category. 这应该只为每个类别带回一个可枚举的字符串( tasks.name )。 The driver will be inspecting this projection and only pull back the tasks.name field. 驱动程序将检查此投影并仅撤回tasks.name字段。

MongoDB doesn't really support projections the way SQL databases do; MongoDB并不像SQL数据库那样真正支持预测; you can ask for a partial document, but you'd still get back something that matches the schema of the document you were querying. 您可以要求提供部分文档,但是您仍然可以找到与您查询的文档架构相匹配的内容。 In your case, you're getting back only the tasks field, and for each task, only the name field. 在您的情况下,您只返回tasks字段,并且每个任务只返回name字段。

You can easily transform this into a list of strings using plain LINQ: 您可以使用普通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();

Alternatively, you can do some fancy stuff with the aggregations API (which does support custom projections, kinda), but that would probably be overkill for you case. 或者,您可以使用聚合API(它确实支持自定义投影,有点)做一些奇特的东西,但这对您来说可能是过度的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM