【问题标题】:select specific field in nested array in mongodb using c#使用c#在mongodb的嵌套数组中选择特定字段
【发布时间】:2014-07-30 23:17:50
【问题描述】:

我的应用程序使用 .net c# 驱动程序访问 mongodb。

我的数据结构是这样的:

{
 "_id" : ObjectId("53d97351e37f520a342e152a"),
  "Name" : "full question test 2",
  "keywords" : ["personality", "extraversion", "agreeableness"],
   "Questions" : [{
     "type" : "likert",
      "text" : "question 1",
       }, 
       {
      "type" : "likert",
      "text" : "question 2",
      }]
}

我想要做的是从问题数组中只选择类型列。

这是我现在的 linq 代码:

from e in collection.AsQueryable<scales>() 
where e.Name == "full question test 2"
select new { e.Id, e.Name, e.Questions}

这将返回所有问题属性(类型和文本)。我只想要类型。我可以通过说诸如 e.Questions[0].text,e.Questions[1].text 之类的话来做到这一点。

但问题的数量因文件而异,所以我想要一个不需要这种手动编码的解决方案。

接受想法!

【问题讨论】:

    标签: c# mongodb mongodb-query aggregation-framework mongodb-.net-driver


    【解决方案1】:

    这里包装的标准查询方法具有一种可用于字段选择的“投影”形式,但这不能执行诸如选择数组元素中的特定字段之类的操作。至少对于多个​​字段。

    但单个字段应该可以使用点符号形式访问元素:

    from e in collection.AsQueryable<scales>() 
    where e.Name == "full question test 2"
    select new { e.Id, e.Name, e.Questions.type }
    

    为了做更多事情,您需要聚合框架可用的投影形式,其中您的“查询”和“投影”使用管道的 $match$project 运算符表示为 BSON 文档。在 shell 形式中,它看起来像这样:

    db.collection.aggregate([
        { "$match": {
            "Name": "fullquestion test 2"
        }},
        { "$project": {
            "Name": 1,
            "Questions.type": 1
        }}
    ])
    

    或者为 C# 构建 BSON 文档:

    var match = new BsonDocument {
        { "$match",new BsonDocument {
               {
                    "Name", "full question test 2"
               }
          }
        }
    };
    
    var project = new BsonDocument {
        { "$project", new BsonDocument {
              { "Name", 1 },
              { "Questions.type": 1 }         
          }
        }
    };
    
    var pipeline = new [] { match, project };
    var result = collection.aggregate(pipeline);
    

    本质上,聚合管道的$project 阶段可以做的不仅仅是选择字段。此处的额外支持允许诸如“更改”数组内文档的结构之类的事情。

    对聚合管道映射到 Linq 的支持正在进行中。您可以在这里监控问题:CSHARP-601

    【讨论】:

    • 你确定 w.r.t.标准查询方法不这样做吗?db.collection.find({"Name": "fullquestion test 2"}, {"Name": 1, "Questions.type": 1}) 返回相同的结果。还是它是 C# 的东西?
    • @JustinCase Brain 在自动驾驶仪上。单场,所以你是对的,标准投影应该适用于单场。仍在考虑多个领域。
    • 感谢您的快速回复!不幸的是,点表示法(id.Questions.type)不起作用:(我收到一条错误消息,提示“System.Array 不包含'type'的定义”
    • @AlexKogan 不确定这是否适用于 linq 的投影上下文,并且还没有时间启动。但是聚合方法确实有效。这只是意味着您不能为此使用 linq 形成查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2016-09-30
    相关资源
    最近更新 更多