Несколько счетчиков с одним запросом в mongodb - PullRequest
0 голосов
/ 30 августа 2018

Я новичок в Mongo Db и был бы признателен за помощь в этом вопросе. Последние пару дней я просеивал посты здесь, разрывая волосы, чтобы посмотреть, смогу ли я найти что-нибудь связанное с моим запросом, но безуспешно.

У меня есть коллекция с документами, похожими по структуре ниже:

_id: xyz
Movieid: 123
MovieName: Titanic
ReleaseDate: 2000-01-01

_id: uvw
Movieid: 456
MovieName: Titanic II
ReleaseDate: 2018-01-01

_id: pqr
Movieid: 789
MovieName: Titanic III
ReleaseDate: 

Я хотел бы получить выходные данные в виде общего количества фильмов, фильмов с датой выпуска и фильмов без даты выпуска в 3 отдельных столбцах, как показано ниже:

Total   |   Released  |     UnReleased
 3      |       2     |          1

Мне удалось написать отдельные запросы для выполнения подсчета, но я не могу успешно объединить все это в один запрос. Конечная цель состоит в том, чтобы создать одно представление, производящее эти значения в качестве выходных данных. Я пытался использовать операторы, такие как $ и, но не могу заставить запрос работать так, как хотелось бы ... это насколько я получил:

db.getCollection("Movies").aggregate(
    $and: [
{ 
            "$match" : 
                {"ReleaseDate":{$exists:true}}
            }
        , 
        { 
            $count:"Total"
        },
        { 
            "$match" : 
                {"ReleaseDate":{$exists:true,$nin:[""]}}
            }
        , 
        { 
            $count:"Released"
        },

        { 
            "$match" : 
                {"ReleaseDate":{$exists:true,$in:[""]}}
            }
        , 
        { 
            $count:"Unreleased"
        }


    ]
);

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

Вы можете использовать ниже агрегации.

$gt > null - проверить, существует поле или нет в выражениях агрегации.

$cond с $sum для вывода 0 и 1 на основе фильтра даты выпуска.

$add для добавления как выпущенного, так и невыпущенного счетчика к итоговой сумме.

db.Movies.aggregate([
 {"$group":{
   "_id":null,
   "Unreleased":{"$sum":{"$cond":[{"$and":[{"$gt":["$ReleaseDate",null]},{"$ne":["$ReleaseDate",""]}]},0,1]}},
   "Released":{"$sum":{"$cond":[{"$and":[{"$gt":["$ReleaseDate",null]},{"$ne":["$ReleaseDate",""]}]},1,0]}}
 }},
 {"$addFields":{"Total":{"$add":["$Unreleased","$Released"]}}}
])
0 голосов
/ 30 августа 2018
db.Movies.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $group: {
                _id: null,
                Total: {
                    $sum: 1
                },
                docs: {
                    $push: '$$ROOT'
                }
            }
        },

        // Stage 2
        {
            $project: {
                _id: 0,
                Total: 1,
                Released: {
                    $filter: {
                        input: "$docs",
                        as: "doc",
                        cond: {
                            $ne: ["$$doc.ReleaseDate", ""]
                        }
                    }
                },
                Unreleased: {
                    $filter: {
                        input: "$docs",
                        as: "doc",
                        cond: {
                            $eq: ["$$doc.ReleaseDate", ""]
                        }
                    }
                },
            }
        },

        // Stage 3
        {
            $project: {
                Total: 1,
                Released: {
                    $size: '$Released'
                },
                UnReleased: {
                    $size: '$Unreleased'
                }
            }
        },

    ]



);
0 голосов
/ 30 августа 2018

Вы можете попробовать ниже $facet агрегация

$count агрегация всегда даст вам значения только для одного соответствующего ($match) условия. Таким образом, вам необходимо дополнительно разделить каждый счетчик на несколько разделов, и это то, что $facet обеспечивает путем обработки нескольких конвейеров агрегации в пределах одной стадии на одном и том же наборе входных документов.

db.collection.aggregate([
  { "$facet": {
    "Total": [
      { "$match" : { "ReleaseDate": { "$exists": true }}},
      { "$count": "Total" },
    ],
    "Released": [
      { "$match" : {"ReleaseDate": { "$exists": true, "$nin": [""] }}},
      { "$count": "Released" }
    ],
    "Unreleased": [
      { "$match" : {"ReleaseDate": { "$exists": true, "$in": [""] }}},
      { "$count": "Unreleased" }
    ]
  }},
  { "$project": {
    "Total": { "$arrayElemAt": ["$Total.Total", 0] },
    "Released": { "$arrayElemAt": ["$Released.Released", 0] },
    "Unreleased": { "$arrayElemAt": ["$Unreleased.Unreleased", 0] }
  }}
])

выход

[{
    "Total": 3,
    "Released": 2,
    "Unreleased": 1
}]
...