Включить поля в агрегат mongodb - PullRequest
0 голосов
/ 15 мая 2018

У меня есть следующая коллекция:

{"orderID" : "30688", "branch" : "CO", "customerID" : "11396783", "customerEmail" : "foo@bar.com"}
{"orderID" : "30688", "branch" : "CO", "customerID" : "11396783", "customerEmail" : "foo@bar.com"}
{"orderID" : "30688", "branch" : "CO", "customerID" : "11396783", "customerEmail" : "foo@bar.com"}
{"orderID" : "89765", "branch" : "CO", "customerID" : "54157526", "customerEmail" : ""}
{"orderID" : "89765", "branch" : "CO", "customerID" : "54157526", "customerEmail" : ""}
{"orderID" : "21546", "branch" : "CO", "customerID" : "20103585", "customerEmail" : "xxx@yyy.com"}
{"orderID" : "21546", "branch" : "CO", "customerID" : "20103585", "customerEmail" : "xxx@yyy.com"}
{"orderID" : "21546", "branch" : "KA", "customerID" : "89374792", "customerEmail" : "aaa@ccc.com"}
{"orderID" : "21794", "branch" : "NY", "customerID" : "78125522", "customerEmail" : ""}

Мне нужно получить все уникальные идентификаторы customerID в определенной ветви, для которой customerEmail не равен NULL.То, что я ожидаю для "филиала": "CO"

{"customerID" : "11396783", "customerEmail" : "foo@bar.com"}
{"customerID" : "20103585", "customerEmail" : "xxx@yyy.com"}

Пока я пробовал:

db.collection.aggregate([
    { $match: { branch: "CO" } },   
    { $group:
        {
            _id: { customer:"$customerID"}
        }
    },
    {
        $group: {_id:"$_id.customer"}
    },
    {
        $addFields: {  email: "$customerEmail"} 
    }
]);

, но это не приносит поле электронной почты.

1 Ответ

0 голосов
/ 15 мая 2018

Не включает поле, потому что вы не просили вернуть поле.Здесь вам не хватает $first или аналогичного "аккумулятора" , чтобы вернуть элемент во время $group.

Также, если вам не нужен пустой адрес электронной почты, исключите его из этапа конвейера $match, поскольку это наиболее эффективный способ.

db.collection.aggregate([
    { $match: { branch: "CO", "customerEmail": { "$ne": "" } } },
    { $group:
        {
            _id: { customer:"$customerID"},
            email: { "$first": "$customerEmail" }
        }
    }
]);

A«pipe» возвращает «выходные данные» только из таких этапов, как $group или $project, которые вы на самом деле запрашиваете.Как и в случае с оператором «Unix pipe» |, «следующий этап» - это только то, что вы выводите.

Это должно быть просто видно из:

db.collection.aggregate([
    { $match: { branch: "CO" } },   
    { $group:
        {
            _id: { customer:"$customerID"}
        }
    }
]);

иличётное:

db.collection.aggregate([
    { $match: { branch: "CO" } },   
    { $project:
        {
            _id: { customer:"$customerID"}
        }
    }
]);

которое, конечно, возвращает только значение _id, так как это все, что вы просили.

У вас есть доступ только на любой стадии конвейера к данным, которые были "выведены"предыдущим этапом ».В пределах $group это означает только _id для ключа группировки и все, что было указано «явно» с использованием действительного «аккумулятора» для любогодругие свойства, которые вы хотите вернуть.Подойдет любой аккумулятор (действительный для «строки»), но все, что находится за пределами _id , должно использовать «аккумулятор» .

Iпредлагаем уделить время просмотру всех операторов агрегирования и их действию.Есть пример использования с каждым оператором

...