C# 上投影中的 $map 和 $filter - 代码示例

$map and $filter in a projection on C# - code example

我想使用 C# mongodb 驱动程序本机函数的聚合框架的 $map 和 $filter 选项。

有什么办法吗?如果是的话,你能放一些代码示例吗?

我搜索了 Mongo 数据库的官方文档,但一无所获。

以下代码在 mongo shell 脚本中,我想翻译成 C# mongodb 驱动程序。

var pipeline = 
[
    {
        $match:{
            ExId: {$in: [ObjectId('5d112f91cb865c02b0714d56'), ObjectId("5d168d2c305196e45e73f4a7")]}
        }
    },
    {
        $project:{
            ExId: 1,
            ArrayObject: {
                $map:{
                    'input': '$ArrayObject',
                    'as': 'itemA',
                    'in':{
                        'Name': '$$itemA.Name',
                        'FilterHere': {
                            $filter: {
                                input: '$$itemA.FilterHere',
                                as: 'item',
                                cond: {
                                    $eq: ['$$item.Sent', true]
                                }
                            }
                        }
                    }                        
                }
            }
        }
    }
]

db.getCollection('MyColection').aggregate(pipeline)

我希望将以下输出输出到 C# 对象中:

{
    "_id" : ObjectId("5d444527cb865d28e8572d8d"),
    "ExId" : ObjectId("5d112f91cb865c02b0714d56"),
    "ArrayObject" : [ 
        {
            "Name" : 130774,
            "FilterHere" : [ 
                {
                    "Code" : 15900181,
                    "SentDate" : ISODate("2019-08-02T11:13:11.732Z"),
                    "Sent" : true
                }, 
                {
                    "Code" : 15900184,
                    "SentDate" : ISODate("2019-08-02T11:13:11.735Z"),
                    "Sent" : true
                }
            ]
        }
    ]
}

谢谢。

您可以找到 MongoDB C# 驱动程序聚合文档 here。要在 C# 驱动程序中构建聚合管道,您有 3 个选项。

  1. 您可以使用 LINQ 进行聚合,但是 LINQ 和 Mongo 查询语言之间并不总是 1:1 映射。
  2. 您可以使用特定的驱动程序 Builder class.
  3. 您可以使用 BsonDocument 构建器构建 "raw" 聚合。使用此方法的类型安全性有限或没有类型安全性。

前 2 个选项要求您创建适当的 classes,因为编译器将强制执行类型安全。

您提供给选项 3 的聚合的 "raw" 转换相当简单,尽管有点冗长。

var foo = new BsonDocument("$project",
new BsonDocument("ExId", 1).Add("ArrayObject",
    new BsonDocument("$map",
        new BsonDocument("input", "$ArrayObject").Add("as", "itemA").Add("in",
            new BsonDocument("Name", "$$itemA.Name").Add("$filter",
                new BsonDocument("input", "$$itemA.FilterHere").Add("as", "item").Add("cond",
                    new BsonDocument("$eq", new BsonArray().Add("$$item.Sent").Add(true))))))));

不幸的是,由于我不知道您的输入 class 是什么样的,所以我很难将您的管道直接转换为代码。但是,查看 Expressions Documentation,似乎 $map 用于 .Select LINQ,$filter 用于 .Where LINQ。这意味着,您的代码看起来像

col.Aggregate()
.Match(doc => ids.Contains(doc.ExId))
.Project(doc => 
    new {
        ExId = doc.ExId,
        ArrayObject = doc.ArrayObject.Select(x =>
            new
            {
                Name = x.Name,
                FilterHere = x.FilterHere.Where(y => y.Sent == true)
            })
        });

因为我没有你的真实 classes,所以我只能猜测它们的样子,StartObject 是我最好的猜测。