我不确定标题是否符合我的要求,但这里是: 我有一个看起来像这样的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"
}
]
}
我希望能够使用学生名字和姓氏来阅读该文档,但我想只返回该学生的数组项目以及其余的json,并排除其他学生,例如,说我的疑问是:
db.Class.find({"Student.FirstName" : "Jane", "Student.LastName" : Smith"})
我希望我的回归json看起来像这样:
[
{
"Class" : "Math",
"Location" : "South Hall",
"Professor" : "Donald Duck"
"Student":
{
"FirstName" : "Jane",
"LastName" : "Smith",
"DOB" : "1990",
"SS": "023456789"
}
}
任何想法如何做到这一点?我正在使用C#驱动程序,我的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; }
}
答案 0 :(得分:1)
首先,你的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驱动程序获取所需内容的示例代码。
从db:
加载集合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。可能的解决方案是生成root对象的新实例(在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;
})
答案 1 :(得分:0)
尝试以下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"
}
}
希望这会有所帮助。