MongoDb 查询到 poco 项目的单个数组项

MongoDb query into poco project a single array item

我不确定标题是否符合我要查找的内容,但它是: 我有一个看起来像这样的 json:

[
{
    "Class" : "Math",
    "Location" : "South Hall",
    "Professor" : "Donald Duck"
    "Student": 
    [
        {
            "FirstName" : "John",
            "LastName" : "Doh",
            "DOB" : "1990",
            "SS": "123456789"

        },
        {
            "FirstName" : "Jane",
            "LastName" : "Smith",
            "DOB" : "1990",
            "SS": "023456789"

        },
        {
            "FirstName" : "John",
            "LastName" : "Smith",
            "DOB" : "1995",
            "SS": "003456789"

        }

    ]
}

]

我希望能够使用学生的名字和姓氏来阅读文档,但我只想 return 这个学生的数组项以及 json 的其余部分,并且排除其余学生,例如,假设我的查询是:

db.Class.find({"Student.FirstName" : "Jane", "Student.LastName" : Smith"})

我希望我的 return json 看起来像这样:

[
{
    "Class" : "Math",
    "Location" : "South Hall",
    "Professor" : "Donald Duck"
    "Student": 
    {
        "FirstName" : "Jane",
        "LastName" : "Smith",
        "DOB" : "1990",
        "SS": "023456789"

    }
}

]

知道怎么做吗?我正在使用 C# driver,我的 poco 看起来像这样:

  public class Rootobject
{
    public string Class { get; set; }
    public string Location { get; set; }
    public string Professor { get; set; }
    public Student Student { get; set; }
}

public class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string DOB { get; set; }
    public string SS { get; set; }
}

尝试以下方法aggregate

db.collection.aggregate(
[ 
    { $unwind: "$Student" },
    { $match: {"Student.FirstName" : "John", "Student.LastName" : "Doh"}}, 
    { $unwind: "$Student" },
    { $project: { "Student" : 1 , "Professor" : 1, "Class" : 1, "Location" : 1, "_id" : 0}}
]
);

输出:

{
    "Class" : "Math",
    "Location" : "South Hall",
    "Professor" : "Donald Duck",
    "Student" : {
        "FirstName" : "John",
        "LastName" : "Doh",
        "DOB" : "1990",
        "SS" : "123456789"
    }
}

希望这对您有所帮助。

首先你的POCO类是错误的。您的根对象上没有一个学生,而是一群学生。

public class Rootobject
{
    public int Id { get; set;}
    public string Class { get; set; }
    public string Location { get; set; }
    public string Professor { get; set; }
    public Student[] Student { get; set; }
}

这是一个示例代码,可以使用 c# MongoDb 驱动程序获得您想要的内容。

从数据库加载集合:

var client = new MongoClient("mongodb://localhost:27017");
var db = client.GetDatabase("testdb");

var collection = db.GetCollection<Rootobject>("students");

从mongo获取数据:

collection.Find(r => r.Student.Any(s => s.FirstName == "Jane" && s.LastName == "Smith"))
.Project(
        Builders<Rootobject>.Projection.Include(x=>x.Class)
        .Include(x=>x.Location)
        .Include(x=>x.Professor)
        .ElemMatch(x=> x.Student, y=>y.FirstName=="Jane" && y.LastName=="Smith"))   
.ToEnumerable()

此查询结果可能会遇到的问题是:您将得到 BSonDocument,而不是 rootobject。可能的解决方案是生成根对象的新实例(在 ToEnumerable() 之后直接使用):

.ToEnumerable()
.Select(r => new Rootobject {
            Class = r[nameof(Rootobject.Class)].AsString, 
            Location = r[nameof(Rootobject.Location)].AsString,
            Professor = r[nameof(Rootobject.Professor)].AsString,
            Student = r[nameof(Rootobject.Student)].AsBsonArray.Select(s => new Student 
                { 
                    DOB = s[nameof(Student.DOB)].AsString,
                    FirstName = s[nameof(Student.FirstName)].AsString,
                    LastName = s[nameof(Student.LastName)].AsString,
                    SS = s[nameof(Student.SS)].AsString,
                }).ToArray(),
            })

其他可能性:您将包含所有学生的根对象获取到客户端并在查询结果中过滤您的学生:

var result = collection
     .Find(r => r.Student
                 .Any(s => s.FirstName == "Jane" && s.LastName == "Smith")).ToEnumerable()
.Select(r =>
{
    r.Student = r.Student.Where(s => s.FirstName == "Jane" && s.LastName == "Smith")
                         .ToArray();
    return r;
})