Необходимо создать структурированный документ из коллекции MongoDB - PullRequest
0 голосов
/ 03 сентября 2018

У нас есть коллекция MongoDB вот так:

{
        a : string, nullable
        b : string, nullable
        c : boolean, not nullable
        d : string, nullable
        e : number, nullable 
}

из которых нам нужен такой результат:

{
       ab : {
              a: <count of a where a is not blank or null>,
              b: <count of b where b is not blank or null>
            },
        c : {
              true: <count of c where c true>,
              false: <count of c where c false>
            },
        d : [<all distinct/unique values of d],
        e : {
              average : <average value of e>,
              min     : <minimum value of e>,
              max     : <maximum value of e>
            }
}   

Мы не хотим запускать несколько find запросов и манипулировать результатами в памяти для получения результатов.

Как нам этого добиться, используя только запросы MongoDB? Любые предложения будут оценены

1 Ответ

0 голосов
/ 03 сентября 2018

Вам нужно запустить несколько конвейеров, а затем объединить результаты. Это возможно с оператором $ facet . Попробуйте запрос ниже:

db.col.aggregate([
    {
        $facet: {
            q1: [
                { $match: { a: { $exists: true, $ne: null }  } },
                { $count: "total" }
            ],
            q2: [
                { $match: { b: { $exists: true, $ne: null }  } },
                { $count: "total" }
            ],
            q3: [
                { $match: { c: true } },
                { $count: "total" }
            ],
            q4: [
                { $match: { c: false } },
                { $count: "total" }
            ],
            q5: [
                {
                    $group: {
                        _id: null,
                        unique: { $addToSet: "$d" }
                    }
                }
            ],
            q6: [
                {
                    $group: {
                        _id: null,
                        average: { $avg: "$e" },
                        min: { $min: "$e" },
                        max: { $max: "$e" },
                    }
                }
            ],
        }
    },
    {
        $project: {
            q1: { $arrayElemAt: [ "$q1", 0 ] },
            q2: { $arrayElemAt: [ "$q2", 0 ] },
            q3: { $arrayElemAt: [ "$q3", 0 ] },
            q4: { $arrayElemAt: [ "$q4", 0 ] },
            q5: { $arrayElemAt: [ "$q5", 0 ] },
            q6: { $arrayElemAt: [ "$q6", 0 ] }
        }
    },
    {
        $project: {
            "ab.a": { $ifNull: [ "$q1.total", 0 ] },
            "ab.b": { $ifNull: [ "$q2.total", 0 ] },
            "c.true": { $ifNull: [ "$q3.total", 0 ] },
            "c.false": { $ifNull: [ "$q4.total", 0 ] },
            d: "$q5.unique",
            "e.average": "$q6.average",
            "e.min": "$q6.min",
            "e.max": "$q6.max",
        }
    }
])

То есть q1-q6 - это просто отдельные конвейеры агрегации. Каждый из них возвращает массив результатов, которые можно преобразовать в отдельные вложенные документы, используя $ arrayElemAt . Затем вы можете использовать простой $project, чтобы преобразовать его в конечный результат. Использование $ addToSet для получения уникальных значений для d и $ ifNull для замены этих подсчетов, когда значение по умолчанию 0.

отсутствует.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...