MongoDb:使用c#和可变结构的文档
本文关键字:结构 文档 使用 MongoDb | 更新日期: 2023-09-27 18:14:20
我有一个HTML表单,它创建具有动态结构的文档。下面是一些用户插入的数据示例。
一个非常简单的文档
{
"name" : "Simple element",
"notes" : "Lorem ipsum rocks",
"values" : [
{
"name" : "An array with 2 values",
"value" : [ 100,200],
"editable" : true
}
]
}
和更复杂的文档
{
"name" : "Complex element",
"notes" : "Lorem ipsum rocks",
"values" : [
{
"name" : "A text value",
"value" : "ABCDEF",
"editable" : true
},
{
"name" : "A numeric value",
"value" : 100,
"editable" : false
},
{
"name" : "A array of 4 values",
"value" : [1,2,3,4],
"editable" : false
},
{
"name" : "A matrix 2x4",
"value" : [[1,2,3,4],[5,6,7,8]],
"editable" : false
}
]
}
文档必须在MongoDB中使用c# MongoCharp驱动程序和NancyFX保存。目前POST是以这种方式实现的,但我不确定这是否是处理动态结构对象的正确方法
Post["/api/docs"] = _ =>
{
//looking for better solution
var json = Request.Body.AsString();
var item = BsonDocument.Parse(json);
database.GetCollection("docs").Insert(item);
return new Response { StatusCode = HttpStatusCode.Created };
};
但是无法找到GET方法的好解决方案
Get["/api/docs"] = _ =>
{
//looking for solution
};
对于这种情况,你认为最好的解决方案是什么?
还有一种方法可以解决这个问题。我们称之为"强类型解决方案"。我已经创建了两个POCO对象
public class DocumentItem
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public String Id { get; set; }
public String Name { get; set; }
public String Notes { get; set; }
public SubItem[] Values { get; set; }
}
public class SubItem
{
public String Name { get; set; }
public Boolean Editable { get; set; }
public Object Value { get; set; }
}
在模块中读取数据的实现如下所示
Get["/api/docs/{id}"] = p => database.GetCollection<DocumentItem>("docs")
.FindOne(Query<DocumentItem>.EQ(x => x.Id, (string)p.id));
Get["/api/docs"] = _ => database.GetCollection<DocumentItem>("docs")
.FindAll()
.ToList();
,我可以这样为插入使用绑定
Post["/api/docs"] = _ =>
{
var item = this.Bind<DocumentItem>();
database.GetCollection("docs").Insert(item);
return item;
};
如果你只是想从MongoDB返回的json文档尝试这样的东西
Get["/api/docs/{category}"] = _ =>
{
var filterValue = _.category;
//Search the DB for one record where the category property matches the filterValue
var item = database.GetCollection("docs").FindOne(Query.EQ("category", filterValue))
var json = item.ToJson();
var jsonBytes = Encoding.UTF8.GetBytes(json );
return new Response
{
ContentType = "application/json",
Contents = s => s.Write(jsonBytes, 0, jsonBytes.Length)
};
};