【问题标题】:No matching creator found未找到匹配的创建者
【发布时间】:2015-09-24 20:37:49
【问题描述】:

最近我从 mongosharp 1.8 迁移到 2.0。我遇到的唯一问题是日期字段的聚合。让我向您展示我如何构造查询:

var aggregateResult = Items.Aggregate()
    .Group(
        g => new {
            // some fields
            Day = g.DateTime.DayOfYear
        },
        z => new {
            MyKey = z.Key
            // agrregation functions
        })
    .Project(
        d => new {
            // projection for other fields
            d.MyKey.Day
        });

我使用了来自documentationthis 示例。

我遇到了以下异常:No matching creator found. 我检查了生成的查询并手动执行了它 - 结果很完美。复制测试代码并与我的比较后,我发现问题出在日期上。那么,谁能指出我纠正日期的语法/查询规则?下面生成的查询证明查询是正确的。

aggregate(
[
    {
        "$group" : {
            "_id" : {
                "Day" : {
                    "$dayOfYear" : "$DateTime"
                }
            },
        }
    },
    {
        "$project" : {
            "Day" : "$_id.Day",
            "_id" : 0
        }
    }
])

解决方法

所以,为了让事情顺利进行,我会采取下一个解决方法:

  • 创建聚合帮助器类,该类使用旧程序集封装对数据库的访问。
  • 实现使用在 bson 文档上构建的查询的方法
  • 将其注入我的 async 2.0 服务并用 sync 替换异步调用

下面是获取集合和执行查询的代码

_collection = new MongoDatabase(new MongoServer( MongoServerSettings.FromUrl(connectionString)), databaseName, new MongoDatabaseSettings()).GetCollection<MyClass>("collection_name"); 
var pipeline = new[] { match, groupBy, project, .... };
_collection.Aggregate(new AggregateArgs { Pipeline = pipeline }).ToList()

【问题讨论】:

  • 你能添加Items的定义吗?
  • @RomanDibikhin, Database.GetCollection("collection_name") .... 用作 IMongoCollection
  • 明天我会重现你的问题。

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


【解决方案1】:

我今天遇到了这个错误。与提出问题的人类似,我从 mongo 查询中填充了一个匿名类型。

当您获取的元素在数据库中不存在时,似乎会发生错误。在这种情况下,mongo 驱动程序似乎对生成的匿名类型应该生成为什么“类型”感到困惑。

我将匿名类型更改为具体类型(通过为其声明一个类)并修复了错误。

【讨论】:

  • 创建类解决了同样的问题,我很幸运找到了这个答案,哇
  • 是的,这实际上也解决了我的问题。
【解决方案2】:

对于像我这样使用 LINQ 查询的人,您还可以考虑在 Select 中使用 coalesce expression (aka ??) 以避免创建不必要的具体类型。

在编写以下示例时使用了 MongoDB.Driver 2.11.2

考虑这个查询:

var query = Collection
    .Where(x => filter.Inject())
    .Select(x => new
    {
        Title = x.Title // Some old entities do not have Title
    });

查询将被翻译成$project like:

aggregate([{ "$project" : { "Title" : "$title" } }])

当某些项目没有$title时,由于@r-j所述的原因,结果无法映射到匿名类型,并引发异常:

找不到匹配的创建者。

如果对x.Title 应用合并:

new
{
    Title = x.Title ?? null
}

那么查询会被翻译成:

aggregate([{ "$project" : { "Title" : { "$ifNull" : ["$title", null] } } }])

以哪种方式保证结果中出现Title

这种方法的缺点是,如果从 C# 的角度来看,C# 表达式确实看起来有点混乱。如果启用可为空的引用类型并且在 C# 中 Title 属性不为空,您将看到一条警告/提示,指出左操作数永远不会为空。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2020-10-07
    相关资源
    最近更新 更多