最新版本的MongoC#驱动程序的聚合功能问题

时间:2018-07-30 14:47:53

标签: c# .net mongodb mongodb-.net-driver

我有使用MongoDB的.NET应用程序。我正在使用的当前驱动程序是1.9.2。我正在尝试将其升级到2.7.0。

在使汇总查询在新版本中工作时,我遇到了一些困难:

驱动程序1.9.2版中的工作代码为:

    public IEnumerable<Car> GetCarsModifiedInPeriod(DateTimeOffset dateFrom, DateTimeOffset dateTo)
    {
        var matchRequestFromDate = new BsonDocument
        {
            {
                "$match",
                new BsonDocument
                {
                    {
                        // Filter out those too recently modified
                       "LastUpdatedOn.0", new BsonDocument {{"$gte", dateFrom.Ticks}}
                    }
                }
            }
        };
        var matchRequestToDate = new BsonDocument
        {
            {
                "$match",
                new BsonDocument
                {
                    {
                        // Filter out those too recently modified
                        "LastUpdatedOn.0", new BsonDocument {{"$lte", dateTo.Ticks}}
                    }
                }
            }
        };

        var cars = collection.Aggregate(new AggregateArgs
        {
            Pipeline = new[] { matchRequestFromDate, matchRequestToDate},              
            AllowDiskUse = true,
            // Setting the OutputMode to Cursor allows us to return Mongo Doc Size > 16 MB - in the case when a large date  
            // range is used or a large number of cars were modified in a short period of time
            OutputMode = AggregateOutputMode.Cursor
        }).Select(r => r.Values.Select(c => c.AsObjectId.ToString()).First());

        var returnData = collection.AsQueryable().Where(c => cars.Contains(c.Id)).Select(c => c);

        return returnData;
    }

在两个指定的returnData上设置断点的情况下,我得到了25辆汽车的计数,这正是我的期望。

这是我尝试为驱动程序2.7.0版重写的方式:

    public IEnumerable<Car> GetCarsModifiedInPeriod(DateTimeOffset dateFrom, DateTimeOffset dateTo)
    {
        var matchRequestFromDate = new BsonDocument
        {
            {
                "$match",
                new BsonDocument
                {
                    {
                        // Filter out those too recently modified
                       "LastUpdatedOn.0", new BsonDocument {{"$gte", dateFrom.Ticks}}
                    }
                }
            }
        };
        var matchRequestToDate = new BsonDocument
        {
            {
                "$match",
                new BsonDocument
                {
                    {
                        // Filter out those too recently modified
                        "LastUpdatedOn.0", new BsonDocument {{"$lte", dateTo.Ticks}}
                    }
                }
            }
        };

        var pipeline = new[] {matchRequestFromDate, matchRequestToDate};
        //var mongoPipeline = new AggregateArgs { Pipeline = pipeline, AllowDiskUse = true, OutputMode = AggregateOutputMode.Cursor };

        var aggregate = collection.Aggregate(); //.Match(mongoPipeline);

        aggregate.Options.AllowDiskUse = true;
        aggregate.Options.UseCursor = true;

        foreach (var pipe in pipeline)
        {
            aggregate.AppendStage<BsonDocument>(pipe);
        }

        var returnData = aggregate.ToList();

        return returnData;  
    }

如果通过这种方法在returnData中设置一个断点,我会得到大约1万辆汽车的计数,因此看起来我正确地应用了相同的匹配项

1 个答案:

答案 0 :(得分:1)

您是否有理由在BsonDocument内做所有事情?有一些方法可以使您的生活更加轻松,例如这样的事情。

collection.Aggregate(new AggregateOptions() { AllowDiskUse = true, UseCursor = true })
.Match(Builders<BsonDocument>.Filter.Gte("LastUpdatedOn.0", dateFrom.Ticks) & Builders<BsonDocument>.Filter.Lte("LastUpdatedOn.0", dateFrom.Ticks))
.ToListAsync()

通过为集合和构建器使用正确的类,您还可以整理更多过滤条件。

在查询中,我不确定您是否甚至需要使用聚合,除非您要做的不仅仅是匹配。可能只是一个发现。