2017-05-24 5 views
1

Meine erste Sammlung employeecategory ist wie folgt;Aggregationsfilter und Lookup auf Mongodb

[{ 
    name: "GARDENING" 
    }, 
    { 
    name: "SECURITY" 
    }, 
    { 
    name: "PLUMBER" 
    } 
] 

Meine zweite Sammlung complaints ist wie folgt;

[{ 
    communityId: 1001, 
    category: "SECURITY", 
    //other fields 
}, { 
    communityId: 1001, 
    category: "GARDENING", 
    //other fields 
}] 

Ich versuche, oben genannten Tabellen beizutreten und das folgende Ergebnis zu erhalten;

Auch wenn es keine Datensätze in Sammlung 2 gibt, muss ich zählen. Ich habe unter Aggregation versucht, aber nicht funktioniert. Wenn ich die Match-Bedingung entfernt habe, funktioniert es, aber ich muss nach der Community-ID filtern. Könnten einige bitte den besten Weg vorschlagen, dies zu erreichen. Mongo DB-Version ist 3.4.0

db.employeecategory.aggregate(
    [{ 
    $match: { 
     "complaints.communityId": 1001 
    } 
    }, { 
    "$lookup": { 
     from: "complaints", 
     localField: "name", 
     foreignField: "category", 
     as: "embeddedData" 
    } 
    }] 
) 
+1

Es wäre besser, Text als Bilder zu haben. –

+0

Wie sieht Ihre Ausgabe aus und was erwarten Sie? – Astro

+0

Sie müssen '$ match' ** verwenden, nachdem ** Sie die' $ lookup' ausgeführt haben. Bevor Sie tatsächlich nach $ suchen, gibt es dort keine Daten. Beachten Sie auch, dass Sie den Ausgabepfad 'embeddedData' aufrufen. Alles, was Sie aus den "verbundenen" Daten referenzieren, befindet sich in diesem Pfad. d. h. "embedded.Data.communityId" '. Und beachte, dass das Feld, das von '$ lookup' erzeugt wird, ein" Array "ist, also musst du es" abwickeln ". Wenn Sie hier einfach das Zeichen "$ match" entfernen, wird Ihnen zumindest angezeigt, wie die "verbundene Ausgabe" aussieht, und Sie erhalten ein klareres Bild davon, wie Sie vorgehen sollen. –

Antwort

0

Es war nicht möglich, sowohl die Filterung für communityId = 1001 und Gruppierung zu erreichen, ohne count = 0 Kategorie in einer einzigen Aggregation zu verlieren. Die erste Möglichkeit besteht darin, ausgehend von complaints collection die Objekte communityId = 1001 zu filtern und eine temporäre Sammlung zu erstellen. Dann von employeecategory Sammlung, $lookup mit dieser Temp-Sammlung zu verbinden, und $group mit name, werden Sie Ihr Ergebnis an diesem Punkt haben, dann legen Sie die Temp-Tabelle.

// will not modify complaints document, will create a filtered temp document 
db.complaints.aggregate(
    [{ 
     $match: { 
     communityId: 1001 
     } 
    }, 
    { 
     $out: "temp" 
    } 
    ] 
); 

// will return the answer that is requested by OP 
db.employeecategory.aggregate(
    [{ 
    $lookup: { 
     from: "temp", 
     localField: "name", 
     foreignField: "category", 
     as: "array" 
    } 
    }, { 
    $group: { 
     _id: "$name", 
     count: { 
     $sum: { 
      $size: "$array" 
     } 
     } 
    } 
    }] 
).pretty(); 

db.temp.drop(); // to get rid of this temporary collection 

wird sich ergeben;

{ _id: "PLUMBER", count: 0}, 
{ _id: "SECURITY", count: 2}, 
{ _id: "GARDENING", count: 1} 

für die Testdaten die ich je hatte;

db.employeecategory.insertMany([ 
    { name: "GARDENING" }, 
    { name: "SECURITY" }, 
    { name: "PLUMBER" } 
]); 

db.complaints.insertMany([ 
    { category: "GARDENING", communityId: 1001 }, 
    { category: "SECURITY", communityId: 1001 }, 
    { category: "SECURITY", communityId: 1001 }, 
    { category: "SECURITY", communityId: 1002 } 
]); 
Verwandte Themen