sql >> Database >  >> NoSQL >> MongoDB

Selecteer Groeperen op aantal en verschillende tellingen in dezelfde mongodb-query

Je begint hier in de goede richting te denken terwijl je in de goede richting ging. Je SQL-mentaliteit veranderen, "distinct" is eigenlijk gewoon een andere manier om een ​​$group te schrijven bediening in beide talen. Dat betekent dat je twee . hebt groepsoperaties die hier plaatsvinden en, in termen van aggregatiepijplijn, twee pijplijnfasen.

Gewoon met vereenvoudigde documenten om te visualiseren:

{
    "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"
}

Het spreekt vanzelf dat voor de gegeven "campagne"-combinatie het totale aantal en het "onderscheiden" aantal respectievelijk "3" en "2" zijn. Dus het logische om te doen is eerst al die "subscriber_id" -waarden "groeperen" en het aantal exemplaren voor elk bijhouden, dan terwijl u "pijplijn" denkt, "totaal" die tellingen per "campagne" en dan gewoon de "telt" onderscheiden" voorvallen als een apart 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 }
    }}
])

Na de eerste "groep" kunnen de uitvoerdocumenten als volgt worden gevisualiseerd:

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

Dus van de "drie" documenten in het voorbeeld, behoren "2" tot de ene afzonderlijke waarde en "1" tot de andere. Dit kan nog steeds worden opgeteld met $sum om de totale overeenkomende documenten te krijgen die u in de volgende fase doet, met het uiteindelijke resultaat:

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

Een echt goede analogie voor de aggregatiepijplijn is de unix-pijp "|" operator, waarmee u bewerkingen kunt "ketenen" zodat u de uitvoer van de ene opdracht kunt doorgeven aan de invoer van de volgende, enzovoort. Als u op die manier begint na te denken over uw verwerkingsvereisten, krijgt u een beter inzicht in de bewerkingen met de aggregatiepijplijn.



  1. Stackexchange.Redis waarom brengt ConnectionMultiplexer.Connect twee clientverbindingen tot stand?

  2. Een open Redis-verbinding behouden met BookSleeve

  3. Hoe een primaire sleutel in MongoDB in te stellen?

  4. Een generieke RedisTemplate opdrogen in het voorjaar 4