2017-02-18 3 views
2

Ich habe einen Übereinstimmungsausdruck in einer Mongodb-Aggregation. Es gibt 3 Felder, die in der Übereinstimmung enthalten sind, aber sie enthalten nicht immer alle Daten. Ich möchte nur die Felder in das Match aufnehmen, wenn das Feld nicht leer ist.Wie mongodb Abfrage dynamisch erstellen

So sieht die Übereinstimmung aus, wenn alle Felder Daten enthalten, aber wenn das für studentGradeLevels verwendete Array leer ist, möchte ich es nicht einschließen oder die Abfrage soll immer noch Daten zurückgeben, die das leere ignorieren Parameter.

$match: { 
    "school._id": "7011", 
    "studentGradeLevels": { $in: ["09", "10", "11", "12"] }, 
    "contentArea": { 
     $in: [ 
      "English 1" 
     ] 
    } 
} 

Gibt es eine Möglichkeit, entweder dynamisch, das Spiel zu bauen, damit ich sind nur die Felder Ich möchte, basierend auf, wenn sie leer sind oder nicht, oder etwas in der Abfrage tun, so dass Parameter, die leer sind, werden ignoriert.

Antwort

2

Sie können $in verwenden, wenn das Array nicht leer ist und $nin wenn das Array leer ist, auf diese Weise das Abgleichsfeld wird nicht berücksichtigt werden ($nin : []):

function buildMatch(arr) { 
    var matcher = {}; 
    if (arr.length == 0) 
     matcher["$nin"] = arr; 
    else 
     matcher["$in"] = arr; 
    return matcher; 
} 

var grades = ["09", "10", "11", "12"]; 
var areas = [ "English 2" ]; 

var gradeMatch = buildMatch(grades); 
var areaMatch = buildMatch(areas); 

db.students.aggregate([{ 
    $match: { 
     "school._id": "7011", 
     "studentGradeLevels": gradeMatch, 
     "contentArea": areaMatch 
    } 
}]) 
+0

es so scheint Antworten Ich denke, das OP wollte dies: "Wenn ich contentArea und schoolGradeLevels abfrage und ein Kandidat doc beide Felder gesetzt hat, dann versuche es. Aber wenn zum Beispiel schoolGradeLevels NICHT im Kandidaten gesetzt ist, dann versuch nicht einmal anzugleichen dieses Feld; versuche einfach auf contentArea zu passen. " –

0

Eine Variation: Prüffelder für Existenz und wenn ja, zu einem besonderen Wert zB ändern _ und fügen hinzu, dass auf die $in Liste: „Was ist, wenn meine Abfrage Parameter leer“

db.foo.aggregate([ 
{$project: {"studentGradeLevels":{$ifNull: ["$studentGradeLevels","_"]}, 
      "contentArea":{$ifNull: ["$contentArea","_"]} 
}} 
,{$match: { 
     "studentGradeLevels": { $in: ["_", "09", "10", "11", "12"] }, 
     "contentArea": { $in: [ "_", "English 1" ] } 
}} 
       ]);