首页 > 解决方案 > Mongo Db在c#中对具有相同数据结构的集合进行查询

问题描述

我想查询更多具有相同数据结构的集合,因此我需要组合这些集合。

我有像 Measurements2016 ,2017 , 2018 等的集合。

但是,如果我重新访问这些集合,我只有 IMongoQuerable 列表中的第一个集合。

目前代码是这样的。

public IMongoQueryable<MeasureDocument> MeasureDocuments()
{
  IMongoQueryable<MeasureDocument> tmpCollection = database.GetCollection<MeasureDocument>($"Measurements2014").AsQueryable();

  for (int i = 2015; i <= DateTime.Now.Year; i++)
  {
    tmpCollection.Union(this.database.GetCollection<MeasureDocument>($"Measurements{i}").AsQueryable());
  }

  return tmpCollection;
} 

为什么这不起作用?

标签: c#mongodbmongodb-.net-driver

解决方案


你不明白 Linq 的方法是如何Union工作的。它不会修改您调用它的集合(在这种情况下tmpCollection)。文档说:

使用默认相等比较器生成两个序列的集合并集。

它的返回类型System.Collections.Generic.IEnumerable<TSource>是两个集合的实际联合。

您的代码应如下所示:

tmpCollection = tmpCollection.Union(this.database.GetCollection<MeasureDocument>($"Measurements{i}").AsQueryable());

编辑

似乎IMongoQueryable不支持Union/Concat操作。您的另一个选择是使用支持集合联合的流畅聚合接口IAggregateFluent 。但是你失去了一些灵活性,因为它没有所有的IMongoQueryable功能。

使用 IAggregateFluent,您的代码将如下所示:

public IAggregateFluent<MeasureDocument> MeasureDocuments()
{
    var aggregation = database.GetCollection<MeasureDocument>($"Measurements2014").Aggregate();

    for (int i = 2015; i <= DateTime.Now.Year; i++)
    {
        aggregation = aggregation.UnionWith(database.GetCollection<MeasureDocument>($"Measurements{i}"));
    }

    return aggregation;
}

然后,如果要过滤聚合,可以执行以下操作:

var filter = Builders<MeasureDocument>
    .Filter
    .Eq(m => m.Field, "2018");

var documentsOf2018 = MeasureDocuments().Match(filter);

最后,您可以调用ToEnumerable()枚举文档:

foreach (var document in documentsOf2018.ToEnumerable())
{
    //...
}

推荐阅读