问题描述
我使用 MongoDB 作为我的数据库存储,并且从 sql 到 Mongo 的查询适应性很好,尽管我不太了解如何实现简单的查询,例如:
- 过滤文档,其中子文档的最后一项将名为“退出”的字段设置为 true。
示例:
{
Name: '',Addresses:
[
{
Street: '',IsDefault: true/false
},{
Street: '',IsDefault: true/false
}
]
}
结果应该是:
所有具有最后一个地址“IsDefault”字段的人都设置为 true,只有那些人。
如果有人能给我提示,不胜感激。
谢谢
解决方法
您并不真正需要 addFields 阶段。只需像这样运行一个比赛阶段:
db.Markets.aggregate(
[
{
$match: {
$expr: {
$eq: [{ $last: "$Positions.ExitCompleted" },true]
}
}
}
])
不幸的是,没有强类型方法 afaik 可以将上述内容转换为 c# 驱动程序查询。
查看 this article 以了解运行此类高级查询的替代方法。
,嗯,
之后我做了一些研究,各种结果为我指明了方向。
我正在使用 MongoDB Compass,所以我在那里构建了聚合并提取到 C#。这可以使用以下方法完成:指南针 >(标签上方 - 聚合)。然后你选择你的阶段。我有以下阶段:
[{$addFields: {
lastExitCompleted: {
$last: '$Positions.ExitCompleted'
}
}},{$match: {
lastExitCompleted: true
}}]
然后我使用“将管道导出到语言”按钮导出到 C#(但是您可以导出到 Compass 支持的可用语言)。
之后我的C#聚合代码如下:
var addFieldsExpr = new BsonDocument("$addFields",new BsonDocument("lastFieldValue",new BsonDocument("$last",$"${nameof(MarketInfo.Positions)}.{nameof(MarketInfoPosition.ExitCompleted)}"))
);
var matchExpr = new BsonDocument("$match",new BsonDocument("lastExitCompleted",exitCompleted) // exitCompleted is bool.
);
var markets = await (await db.Markets
.AggregateAsync(
PipelineDefinition<MarketInfo,MarketInfo>
.Create(addFieldsExpr,matchExpr) <-- this is what makes the job.
))
.ToListAsync();
return markets;
我们可以使用 nameof 来避免表达式中的拼写错误,因为我们没有强类型表达式。
我搜索了一下,好像C#驱动程序不支持$addFields,但如果我错了,请大喊。