sql >> Database >  >> NoSQL >> MongoDB

Aggregatie uitvoeren/kruising instellen op MongoDB

Dit is een enigszins ingewikkelde oplossing. Het idee is om eerst de DB te gebruiken om de populatie van mogelijke paren te krijgen, dan om te draaien en de DB te vragen de paren te vinden in de _user veld. Pas op dat duizenden gebruikers een behoorlijk grote koppelingslijst zullen maken. We gebruiken $addFields voor het geval er meer aan de invoerrecords is dan we in het voorbeeld zien, maar als dat niet het geval is, vervang dan voor efficiëntie door $project om de hoeveelheid materiaal die door de buis stroomt te verminderen.

//
// Stage 1:  Get unique set of username pairs.
//
c=db.foo.aggregate([
{$unwind: "$_user"}

// Create single deduped list of users:
,{$group: {_id:null, u: {$addToSet: "$_user"} }}

// Nice little double map here creates the pairs, effectively doing this:
//    for index in range(0, len(list)):
//      first = list[index]
//      for p2 in range(index+1, len(list)):
//        pairs.append([first,list[p2]])
// 
,{$addFields: {u: 
  {$map: {
    input: {$range:[0,{$size:"$u"}]},
    as: "z",
    in: {
        $map: {
            input: {$range:[{$add:[1,"$$z"]},{$size:"$u"}]},
            as: "z2",
            in: [
            {$arrayElemAt:["$u","$$z"]},
            {$arrayElemAt:["$u","$$z2"]}
            ]
        }
    }
    }}
}}

// Turn the array of array of pairs in to a nice single array of pairs:
,{$addFields: {u: {$reduce:{
        input: "$u",
        initialValue:[],
        in:{$concatArrays: [ "$$value", "$$this"]}
        }}
    }}
          ]);


// Stage 2:  Find pairs and tally up the fileids

doc = c.next(); // Get single output from Stage 1 above.                       

u = doc['u'];

c2=db.foo.aggregate([
{$addFields: {_x: {$map: {
                input: u,
                as: "z",
                in: {
                    n: "$$z",
                    q: {$setIsSubset: [ "$$z", "$_user" ]}
                }
            }
        }
    }}
,{$unwind: "$_x"}
,{$match: {"_x.q": true}}
//  Nice use of grouping by an ARRAY here:
,{$group: {_id: "$_x.n", v: {$push: "$_id.fileid"}, n: {$sum:1} }}
,{$match: {"n": {"$gt":1}}}
                     ]);

show(c2);



  1. Hoe kan ik in MongoDB documenten sorteren op basis van een eigenschap in een ingesloten object?

  2. Mongodb-verbindingen in Java beheren als objectgeoriënteerd

  3. sailsjs gebruiken mongodb zonder ORM

  4. Hoe verschillende datumitems in een tijdstempelveld in Mongoose/NodeJS te tellen?