2017-01-09 59 views
0

我不知道,如果冠军争夺战中我所期待的,但在这里它是: 我有一个JSON看起来像这样:MongoDB中查询到POCO项目单一阵列项目

[ 
{ 
    "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

首先你的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"); 

从蒙戈获取数据:

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()后直接使用)来生成rootobjects的新实例:

.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; 
}) 
+0

@Pacman如果答案对你有帮助,我会感激不尽。 –

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

希望这有助于。