【问题标题】:selecting fields in a document after applying filter on embedded document在嵌入文档上应用过滤器后选择文档中的字段
【发布时间】:2018-11-22 02:38:41
【问题描述】:

您能告诉我以下查询的 C# 等效项吗?

db.RolesNPerm.find(
   { "Roles.Name":{$in:[ "PO","role1","TO"] }},
   { _id: 1, ParentId: 1 }
)

如果嵌入文档(Roles) 中的Name 与列表中的任何值匹配,我正在尝试选择记录中的字段(_idParentId)。

这是我的 MongoDB 文档

{
    "_id" : "1",
    "ParentId" : "par1",
    "Roles" : [ 
        {
            "Name" : "PO",
            "_id" : "5bc08ee1f12541c3aaa03084"
        }
    ]
}

以下是我的查询结果,因为 Role.Name 与名称列表中的“PO”匹配。

{
    "_id" : "1",
    "ParentId" : "par1"
}

【问题讨论】:

  • 你试过什么? SO不是代码转换服务。

标签: c# mongodb nested


【解决方案1】:

有(至少)两种方法可以做到这一点:

您可以使用Builder 类来构建过滤器和投影部分。问题是您不能使用强类型 lambda 表达式来表达 Roles.Name 部分,因此您可以使用 FieldDefinition 类型作为后备

var values = new[] { "PO", "role1", "TO" };
FieldDefinition<Model, string> field = "Roles.Name";

var filter = Builders<Model>.Filter.In(field, values);
var project = Builders<Model>.Projection.Combine(
        Builders<Model>.Projection.Include(x => x._id),
        Builders<Model>.Projection.Include(x => x.ParentId)
    );

var result = Col.Find(filter).Project(project).ToList();

您也可以使用 LINQ 语法,该语法将被翻译成相关的 MongoDB 命令:

var values = new[] { "PO", "role1", "TO" };

var q = from doc in Col.AsQueryable()
        where doc.Roles.Any(x => values.Contains(x.Name))
        select new Model6()
        {
            ParentId = doc.ParentId,
            _id = doc._id
        };

var result = q.ToList();

【讨论】:

  • 非常感谢它提供了非常丰富的信息,非常感谢。我试图在 Lambda 表达式中表达 Roles.Name,因为硬编码文件名不是一个好习惯。我从您的回复中了解到,不可能在 Lambda 中表达所有内容。很高兴知道我们可以在 C# 中使用 Linq 与 MongoDB 交互。我在 Linq 中看到的一个问题是它不是异步的。
  • @user641247 记住 C# 中的 nameof 运算符,您可以构建具有编译时间检查的字符串
猜你喜欢
  • 2019-03-19
  • 2011-01-09
  • 1970-01-01
  • 2019-07-02
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 2018-05-10
相关资源
最近更新 更多