[英]Projection of mongodb subdocument and get subdocument as class in c#
你好。 我有一个名为“ Level”的具有此类结构的集合:
public class Level
{
[BsonId]
public string Id {get; set;}
public string Name { get; set; }
public int Number { get; set; }
public int TotalScore { get; set; }
public int QuestionCount { get; set; }
public IEnumerable<ConnectingQuestion> ConnectingQuestions { get; set; }
}
public class ConnectingQuestion
{
[BsonId]
public string Id { get; set; }
public int QuestionNumber { get; set; }
public string Description { get; set; }
public string Type { get; set; }
public string Title { get; set; }
}
和这样的收集结构:
{
"_id" : "64e850f95322e01e88f131a2",
"Name" : "First Level",
"Number" : NumberInt(1),
"TotalScore" : NumberInt(2690),
"QuestionCount" : NumberInt(40),
"ConnectingQuestions" : [
{
"_id" : "5a130570738634297478fb43",
"QuestionNumber" : NumberInt(1),
"Description" : "desc",
"Type" : "sc",
"Title" : "title1",
},
{
"_id" : "5a130570738634297478fb76",
"QuestionNumber" : NumberInt(2),
"Description" : "desc",
"Type" : "sc",
"Title" : "title2",
},
{
"_id" : "5a130570738634297478fb23",
"QuestionNumber" : NumberInt(3),
"Description" : "desc",
"Type" : "sc",
"Title" : "title3",
}
]
}
{
"_id" : "59e850f95322e01e88f131c1",
"Name" : "Second Level",
"Number" : NumberInt(2),
"TotalScore" : NumberInt(8000),
"QuestionCount" : NumberInt(20),
"ConnectingQuestions" : [
{
"_id" : "5a130570738634297478fa56",
"QuestionNumber" : NumberInt(1),
"Description" : "desc",
"Type" : "sc",
"Title" : "title1",
},
{
"_id" : "5a130570738634297478fb66",
"QuestionNumber" : NumberInt(2),
"Description" : "desc",
"Type" : "sc",
"Title" : "title2",
},
{
"_id" : "5a130570738634297478fe32",
"QuestionNumber" : NumberInt(3),
"Description" : "desc",
"Type" : "sc",
"Title" : "title3",
}
]
}
我需要在C#中编写Query,该查询首先选择具有指定ID的级别并在所选级别中,选择并返回具有“连接问题”类而不是BsonDocument类型的某些“问题编号”的“连接问题”子集合。 这样的伪查询:
ConnectingQuestion cq = MongoDB.Levels.find(level.id == "59e850f95322e01e88f131c1" && level.ConnectingQuestions.QuestionNumber == 2).Projection(level.ConnectingQuestions).SingleOrDefault();
这是两种可能的解决方案-可能有更简单的解决方案...
版本1:仅使用find()
和project()
以及一些BSON魔术
var collection = new MongoClient().GetDatabase("test").GetCollection<Level>("test");
var projection = Builders<Level>.Projection.ElemMatch(level => level.ConnectingQuestions, q => q.QuestionNumber == 2);
var bsonDocument = collection
// filter out anything that we're not interested in
.Find(level => level.Id == "59e850f95322e01e88f131c1")
.Project(projection)
.First();
// get first (single!) item from "ConnectingQuestions" array
bsonDocument = bsonDocument.GetElement("ConnectingQuestions").Value.AsBsonArray[0].AsBsonDocument;
// deserialize bsonDocument into ConnectingQuestions instance
ConnectingQuestion cq = BsonSerializer.Deserialize<ConnectingQuestion>(bsonDocument);
版本2:使用聚合框架( $filter
需要MongoDB> = v3.2)
var collection = new MongoClient().GetDatabase("test").GetCollection<Level>("test");
var cq = collection.Aggregate()
// filter out anything that we're not interested in
.Match(level => level.Id == "59e850f95322e01e88f131c1")
// filter the ConnectingQuestions array to only include the element with QuestionNumber == 2
.Project<Level>("{ 'ConnectingQuestions': { $filter: { input: '$ConnectingQuestions', cond: { $eq: [ '$$this.QuestionNumber', 2 ] } } } }")
// move the first (single!) item from "ConnectingQuestions" array to the document root level
.ReplaceRoot(q => q.ConnectingQuestions.ElementAt(0))
.FirstOrDefault();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.