【问题标题】:MongoDb: documents with variable structure using and C#MongoDb:使用和 C# 的具有可变结构的文档
【发布时间】:2014-07-22 08:53:36
【问题描述】:

我有一个 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
    }
]

}

文档必须使用 C# MongoCharp 驱动程序和 NancyFX 保存在 MongoDB 中。 目前 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
};

您认为这种情况的最佳解决方案是什么?

【问题讨论】:

  • 您想如何查询文档?您要查询哪个字段?
  • 我想取回按属性(例如名称)过滤的文档列表或按 _id 过滤的单个文档
  • 您如何知道要过滤的属性?查询字符串?
  • 我需要在 JSON 对象的顶层添加一个 Category 属性。然后我将按类别过滤,例如Get["/api/docs/:category"]

标签: c# mongodb-.net-driver nancy


【解决方案1】:

还有另一种解决问题的方法。我们称其为“强类型解决方案”。我创建了两个 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;
   };

【讨论】:

    【解决方案2】:

    如果您只是想从 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)
       };
    };
    

    【讨论】:

    • 从 MongoDB 返回 JSON 格式是一种选择。我还找到了一种将示例 JSON 文档映射到 C# 对象中的方法
    猜你喜欢
    • 2015-08-09
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    • 2016-07-24
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多