我正在尝试使用C#.Net查询MongoDB集合。我想根据某些条件过滤集合,然后只投影某些字段,然后将投影转换为键值对。
我能够以我想要的方式过滤和投射。但是我想知道是否有内置方法将投影转换为键值对?
以下是我的mongo数据库文档的样子
{
"_id" : 32178271832,
"url" : "www.somedomain.com",
"fileName" : "somefilename.pdf",
"isDone" : true,
"client" : ObjectId("56g2e67d7gf2208c2dbe33yt"),
"startTime" : ISODate("2015-05-23T18:50:11.271Z"),
"endTime" : ISODate("2015-05-23T18:52:43.819Z"),
"cost" : 30,
"taskGroups" : [
{
"phase" : "phase1",
"name" : "Some Name",
"_id" : ObjectId("43r2e46h7er2208c2geh74e5"),
"tasks" : [
{
"_id" : ObjectId("43r2e46h7er2208c2geh74e5"),
"input" : [],
"predecessors" : []
}
]
}
],
"context" : {
"startTime" : ISODate("2016-03-23T18:50:11.271Z"),
"endTime" : ISODate("2016-03-23T18:52:43.819Z"),
"state" : "GA",
"PHASE1" : {
"hasaccountnumber" : "Yes",
"accountnumber" : 1
"Child1":{
"Property1": "SomeValue1"
"Property2" : "SomeValue2"
}
}
}
}
这是我的代码
public static IDictionary<string,string> GetFromMongo()
{
var collection = _mongodb.GetCollection<BsonDocument>("kunits");
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Eq<bool>("isDone", true) & filterBuilder.Exists("isTransformed", false);
var projection = Builders<BsonDocument>.Projection
.Include("client")
.Include("url")
.Include("fileName")
.Include("context");
var document = collection.Find(filter).Project(projection).FirstOrDefault();
IDictionary<string,string> dictionary = ??
return dictionary;
}
无论如何将文档转换为字典?该文档具有层次结构。
UPDATE2
所以这就是我所做的。但是,如果BsonValue
是JSON,我如何递归处理?例如,在上面的JSON context
元素具有层次结构的情况下,如何递归循环并在字典中添加其每个字段?
var document = collection.Find(filter).Project(projection).FirstOrDefault();
var docs = new Dictionary<string, BsonValue>();
foreach (var elm in document.Elements)
{
//how to recursively process when elm.value is JSON ??
docs.Add(elm.Name, elm.Value);
}
答案 0 :(得分:1)
我不相信FirstOrDefault()在投影上是正确的。有一个ToDictionary方法可以映射你想要的东西:
var document = collection.Find(filter).Project(projection);
var dictionary = documents.ToEnumerable().ToDictionary(key => key.client, value => value.url);
一种不同的方法
var docs = new Dictionary<string, BsonDocument>();
var result = collection.Find(filter).Project(projection);
result.ForEachAsync((bsonDoc) =>
{
string name = bsonDoc.GetValue("[Your Dictionary Key]").AsString;
if (!docs.ContainsKey(name))
{
docs[name] = bsonDoc;
}
});
答案 1 :(得分:0)
终于得到它BsonValue
拥有属性IsBsonDocument
。我们可以检查以确定vaue是JSON还是原始数据类型。然后递归循环
public static Dictionary<string, BsonValue> GetFromMongo()
{
var collection = _mongodb.GetCollection<BsonDocument>("units");
var filterBuilder = Builders<BsonDocument>.Filter;
var filter = filterBuilder.Eq<bool>("isDone", true) & filterBuilder.Exists("isTransformed", false);
var projection = Builders<BsonDocument>.Projection
.Include("client")
.Include("url")
.Include("fileName")
.Include("context");
var document = collection.Find(filter).Project(projection).FirstOrDefault();
var dictionary = new Dictionary<string, BsonValue>();
Recurse(document, dictionary);
return dictionary;
}
private static void Recurse(BsonDocument doc, Dictionary<string, BsonValue> dictionary)
{
foreach (var elm in doc.Elements)
{
if (!elm.Value.IsBsonDocument)
{
if (!dictionary.ContainsKey(elm.Name))
{
dictionary.Add(elm.Name, elm.Value);
}
}
else
{
Recurse((elm.Value as BsonDocument), dictionary);
}
}
}