sql >> Database >  >> NoSQL >> MongoDB

hoe 0 voor week te tonen wanneer geen record overeenkomt met die week in $week mongodb-query

Als $week kan een waarde tussen 0 . retourneren en 53 Ik neem aan dat je 54 . verwacht documenten als resultaat met 0 of niet-nulwaarden voor documentCount . Om dat te bereiken, moet u al uw documenten in één ($ groep -ing door null ) en genereer vervolgens de uitvoer.

Om een ​​reeks getallen te genereren, kunt u $range operator en vervolgens kunt u de uitvoer genereren met $map . Om een ​​reeks documenten om te zetten in meerdere documenten, kunt u $ gebruiken ontspannen .

db.collectionName.aggregate([
    //where query
    { "$match": {  $and:[{CreatedOn:{$lte:ISODate("2018-07-14T13:59:08.266+05:30")}},{CreatedOn:{$gte:ISODate("2018-06-10T13:59:08.266+05:30")}}] } },
    //distinct column 
    {
        "$group": {
            _id: {$week: '$CreatedOn'},
            documentCount: {$sum: 1}
        }
    },
    {
        $group: {
            _id: null,
            docs: { $push: "$$ROOT" }
        }
    },
    {
        $project: {
            docs: {
                $map: {
                    input: { $range: [ {$week:ISODate("2018-06-10T13:59:08.266+05:30")}, {$week:ISODate("2018-07-14T13:59:08.266+05:30")}]},
                    as: "weekNumber",
                    in: {
                        $let: {
                            vars: { index: { $indexOfArray: [ "$docs._id", "$$weekNumber" ] } },
                            in: {
                                $cond: {
                                    if: { $eq: [ "$$index", -1 ] },
                                    then: { _id: "$$weekNumber", documentCount: 0 },
                                    else: { $arrayElemAt: [ "$docs", "$$index" ] }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $unwind: "$docs"
    },
    {
        $replaceRoot: {
            newRoot: "$docs"
        }
    }
])

$indexOfArray gebruiken om te controleren of de array van huidige documenten het document bevat (-1 anders) en $arrayElemAt om een ​​bestaand document op te halen uit docs . Laatste stap ($replaceRoot ) is slechts om één niveau van nesten kwijt te raken (docs ). Uitgangen:

{ "_id" : 0, "documentCount" : 0 }
{ "_id" : 1, "documentCount" : 0 }
{ "_id" : 2, "documentCount" : 0 }
...
{ "_id" : 22, "documentCount" : 0 }
{ "_id" : 23, "documentCount" : 2 }
{ "_id" : 24, "documentCount" : 9 }
{ "_id" : 25, "documentCount" : 1 }
{ "_id" : 26, "documentCount" : 1 }
{ "_id" : 27, "documentCount" : 0 }
...
{ "_id" : 52, "documentCount" : 0 }
{ "_id" : 53, "documentCount" : 0 }

U kunt geretourneerde resultaten eenvoudig aanpassen door de invoer van $map . aan te passen fase. U kunt bijvoorbeeld een reeks consts doorgeven, zoals input: [21, 22, 23, 24] ook.

EDIT:Om de weken tussen gespecificeerde datums te krijgen, kun je $week . gebruiken voor start- en einddatum om de cijfers te krijgen.




  1. Meteoor zonder mongo

  2. Redis Client List doel en beschrijving

  3. Hoe MongoDB Document rechtstreeks naar Jackson JsonNode in Java te converteren

  4. MongoDB:Wat heeft het voor zin om MapReduce te gebruiken zonder parallellisme?