Поле должно быть ошибкой объекта-аккумулятора при попытке группировки по объекту в качестве ключа - PullRequest
1 голос
/ 02 мая 2019

Я пытаюсь печатать безопасные групповые документы по нескольким свойствам из коллекции.Я понял, что проблема не в группировке по нескольким свойствам, а в том, что ключ является объектом (new { }) вместо строки.

Это работает:

collection.Aggregate().Group(x => x.Name, x => new { Name = x.Key, Count = x.Sum(s => 1) }).ToList();

Этоне работает:

collection.Aggregate().Group(x => new { Name = x.Name }, x => new { Name = x.Key.Name, Count = x.Sum(s => 1) }).ToList();

Ошибка:

MongoDB.Driver.MongoCommandException: 'Агрегат команды не пройден: поле' Имя 'должно быть объектом-накопителем.'

Когда я преобразовываю запрос, который не работает, в строку, я получаю следующее:

aggregate([{ "$group" : { "_id" : { "Name" : "$Name" }, "Name" : "$_id.Name", "Count" : { "$sum" : 1 } } }])

Полагаю, проблема в этой части "Name" : "$_id.Name".Как я могу решить эту проблему?

В настоящее время я использую версию 2.8.0 драйвера mongodb.

1 Ответ

2 голосов
/ 02 мая 2019

На самом деле драйвер ведет себя здесь корректно, но вы испытываете ограничение на $ group стадии конвейера в Aggregation Framework. В документации указано, что:

Выходные документы содержат поле _id, в котором содержится отдельная группа по ключу. Выходные документы могут также содержать вычисляемые поля, которые содержат значения некоторого выражения аккумулятор , сгруппированного по полю _id $ group

Так что в вашем случае вы пытаетесь обратиться к полю _id без какого-либо аккумулятора.

С логической точки зрения ваши запросы похожи. Первый переводится на:

{
    "$group" : {
        "_id" : "$Name",
        "Count" : {
            "$sum" : 1
        }
    }
}

Второй будет возвращать те же данные, но у вас есть объект в качестве ключа группировки. Чтобы это исправить, в C # вам нужно ввести выражение .First(), которое будет переведено в $ first , поэтому запустите:

Col.Aggregate()
    .Group(
        x => new { Name = x.Name }, 
        x => new { Name = x.First().Name, Count = x.Sum(s => 1) })
    .ToList();

будет работать под запросом к базе данных:

{
    "$group" : {
        "_id" : {
            "Name" : "$Name"
        },
        "Name" : {
            "$first" : "$Name"
        },
        "Count" : {
            "$sum" : 1
        }
    }
}

Работает, но логически возвращает те же данные, что и первая агрегация

...