sql >> Database teknologi >  >> NoSQL >> MongoDB

Vælg Grupper efter antal og særskilt antal i samme mongodb-forespørgsel

Du begynder at tænke i de rigtige baner her, da du var på vej i den rigtige retning. At ændre din SQL-tankegang, "distinkt" er i virkeligheden bare en anden måde at skrive en $group drift på begge sprog. Det betyder, at du har to gruppeoperationer, der finder sted her, og i aggregerede pipeline-termer, to pipeline-faser.

Bare med forenklede dokumenter at visualisere:

{
    "campaign_id": "A",
    "campaign_name": "A",
    "subscriber_id": "123"
},
{
    "campaign_id": "A",
    "campaign_name": "A",
    "subscriber_id": "123"
},
{
    "campaign_id": "A",
    "campaign_name": "A",
    "subscriber_id": "456"
}

Det er naturligt, at for den givne "kampagne"-kombination er det samlede antal og "distinkt" antal henholdsvis "3" og "2". Så den logiske ting at gøre er at "gruppere" alle disse "subscriber_id"-værdier først og holde optællingen af ​​forekomster for hver, så mens man tænker "pipeline", "total" disse optællinger pr. "kampagne" og derefter bare tælle " distinkt" forekomster som et separat nummer:

db.campaigns.aggregate([
    { "$match": { "subscriber_id": { "$ne": null }}},

    // Count all occurrences
    { "$group": {
        "_id": {
            "campaign_id": "$campaign_id",
            "campaign_name": "$campaign_name",
            "subscriber_id": "$subscriber_id"
        },
        "count": { "$sum": 1 }
    }},

    // Sum all occurrences and count distinct
    { "$group": {
        "_id": {
            "campaign_id": "$_id.campaign_id",
            "campaign_name": "$_id.campaign_name"
        },
        "totalCount": { "$sum": "$count" },
        "distinctCount": { "$sum": 1 }
    }}
])

Efter den første "gruppe" kan outputdokumenterne visualiseres på denne måde:

{ 
    "_id" : { 
        "campaign_id" : "A", 
        "campaign_name" : "A", 
        "subscriber_id" : "456"
    }, 
    "count" : 1 
}
{ 
    "_id" : { 
        "campaign_id" : "A", 
        "campaign_name" : "A", 
        "subscriber_id" : "123"
    }, 
    "count" : 2
}

Så fra de "tre" dokumenter i prøven hører "2" til en særskilt værdi og "1" til en anden. Dette kan stadig summeres med $sum for at få de samlede matchende dokumenter, som du gør i den følgende fase, med det endelige resultat:

{ 
    "_id" : { 
        "campaign_id" : "A", 
        "campaign_name" : "A"
    },
    "totalCount" : 3,
    "distinctCount" : 2
}

En rigtig god analogi for aggregeringsrørledningen er unix-røret "|" operator, som tillader "kæde" af operationer, så du kan sende output fra én kommando til input fra den næste, og så videre. At begynde at tænke på dine behandlingskrav på den måde vil hjælpe dig med at forstå operationer med aggregeringspipelinen bedre.



  1. Fjern indlejret dokument i en indlejret række dokumenter

  2. Dynamisk databaseforbindelse til mongodb eller mongoose fra nodejs

  3. Bulk upsert i MongoDB ved hjælp af mongoose

  4. Selvvært MongoDB