sql >> Databasteknik >  >> NoSQL >> MongoDB

Behöver en distinkt räkning på flera fält som har sammanfogats från en annan samling med hjälp av mongodb aggregeringsfråga

Detta borde göra susen. Jag testade det på din inmatningsuppsättning och lade medvetet till några dupevärden som NYC visas i mer än en DESTINATION för att säkerställa att den blev de-duperad (dvs. distinkt antal som efterfrågats). För skojs skull, kommentera alla steg och sedan uppifrån och ned AVkommentera den för att se effekten av varje steg i pipelinen.

var id = "1";

c=db.foo.aggregate([
// Find a thing:
{$match: {"_id" : id}}

// Do the lookup into the objects collection:
,{$lookup: {"from" : "foo2",
            "localField" : "objectsIds",
            "foreignField" : "_id",
            "as" : "objectResults"}}

// OK, so we've got a bunch of extra material now.  Let's
// get down to just the metaDataMap:
,{$project: {x: "$objectResults.metaDataMap"}}
,{$unwind: "$x"}
,{$project: {"_id":0}}

// Use $objectToArray to get all the field names dynamically:
// Replace the old x with new x (don't need the old one):
,{$project: {x: {$objectToArray: "$x"}}}
,{$unwind: "$x"}

// Collect unique field names.  Interesting note: the values
// here are ARRAYS, not scalars, so $push is creating an
// array of arrays:
,{$group: {_id: "$x.k", tmp: {$push: "$x.v"}}}

// Almost there!  We have to turn the array of array (of string)
// into a single array which we'll subsequently dedupe.  We will
// overwrite the old tmp with a new one, too:
,{$addFields: {tmp: {$reduce:{
    input: "$tmp",
    initialValue:[],
    in:{$concatArrays: [ "$$value", "$$this"]}
        }}
    }}

// Now just unwind and regroup using the addToSet operator
// to dedupe the list:
,{$unwind: "$tmp"}
,{$group: {_id: "$_id", uniqueVals: {$addToSet: "$tmp"}}}

// Add size for good measure:
,{$addFields: {size: {"$size":"$uniqueVals"}} }
          ]);


  1. Mongoose:Sortera alfabetiskt

  2. MongoDB-fråga som jämför 2 fält i samma samling utan $where

  3. Uppdatera modell med Mongoose, Express, NodeJS

  4. Skip/Mock Redis In Junit