如何从 C# 中的 MongoDB IPipelineStageDefinition 获取聚合命令的字段/选项?

问题描述 投票:0回答:1

我需要在单元测试中验证

AggregateAsync
方法是否收到了通过
PipelineDefinition<BsonDocument, BsonDocument>
实例表示的特定聚合命令。 该命令是
$collStats
以及附加字段/选项
storageStats
。 如何检查管道是否完全包含此命令,包括附加字段?

我可以使用 Stages

 获取管道的
各个阶段,因此我可以验证是否只有一个阶段(包含上面的命令),然后获取此阶段:

PipelineDefinition<BsonDocument, BsonDocument> pipeline = ...; // obtained from some callback
IPipelineStageDefinition stage = pipeline.Stages.Single();

现在,我可以使用

$collStats
:
轻松检查此阶段是否包含
OperatorName

命令
if (stage.OperatorName == "$collStats")
{
    // check for additional "storageStats" field
}

但是我如何检查该命令是否还包含字段

storageStats
? 不幸的是,似乎没有像
OperatorFields
这样的类似属性。 我目前找到的唯一解决方案是序列化阶段,然后检查这个序列化表示是否包含特定字段:

using MongoDB.Bson.Serialization;

BsonDocument command = stage.Render(
    BsonSerializer.SerializerRegistry.GetSerializer<BsonDocument>(),
    BsonSerializer.SerializerRegistry).Document;
BsonDocument fields = command.GetValue("$collStats").ToBsonDocument();

if (fields.Contains("storageStats"))
{
    // finally ...
}

这感觉太复杂了,而且是错误的做法。 有没有我缺少的更简单的解决方案?

c# mongodb aggregation-framework mongodb-.net-driver
1个回答
0
投票

要验证 MQL 查询,您必须渲染它。原因是管道可以通过不同的方式创建,并且并不总是基于已渲染的 BsonDocument。 因此,它可能会像上面的代码一样渲染一个阶段,或者渲染整个管道(基本相同):

        var registry = BsonSerializer.SerializerRegistry;
        var serializer = registry.GetSerializer<BsonDocument>();
        var renderedStages = pipeline.Render(serializer, registry).Documents

您还可以在

CommandStartedEvent
上配置事件订阅者(请参阅此处),但我怀疑您在这里需要的是服务器调用

© www.soinside.com 2019 - 2024. All rights reserved.