2017-01-09 58 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" 
    } 
} 

希望這有助於。