2013-10-30 13 views
7

Der folgende Code funktioniert mit keine Querystrings oder ein nur Querstring. Mit anderen Worten, wenn Sie einfach zu /characters gehen, werden alle Zeichen zurückgegeben. Wenn Sie jedoch einen Querystring-Parameter /characters?gender=male angeben, werden nur männliche Zeichen zurückgegeben.Wie erstellt man eine bedingte Abfrage in Mongoose?

Wie konnte ich erweitern diese mit arbeiten entweder , , oder keine querystrings? Ich würde wirklich lieber vermeiden zu schreiben 8 oder 9 verschiedene if-Anweisungen für jeden Fall. Ich hatte gehofft, Mongoose würde einfach ignorieren $ Klausel, wenn es null oder undefined ist, aber das ist nicht der Fall (siehe Code auskommentiert).

var gender = req.query.gender; 
    var race = req.query.race; 
    var bloodline = req.query.bloodline; 

    var query = Character.find(); 

    if (gender) 
    query = query.where('gender').equals(gender); 
    if (race) 
    query = query.where('race').equals(race); 
    if (bloodline) 
    query = query.where('bloodline').equals(bloodline); 

    /* 
    query 
    .where('gender').equals(new RegExp('^' + gender + '$', 'i')) 
    .where('race').equals(new RegExp('^' + race + '$', 'i')) 
    .where('bloodline').equals(new RegExp('^' + bloodline + '$', 'i')); 
    */ 

    query.exec(function(err, characters) { 
    if (err) throw err; 
    res.send(characters); 
    }); 

Edit: Nun, ich denke ich es jetzt mit 7 if-Anweisungen tun könnte. Es sei denn jemand findet eine elegantere Lösung.

Edit 2:

Danke Jungs. Es ist schwierig, eine Antwort auszuwählen, weil Sie beide mir geholfen haben, diese prägnante Lösung zu finden. Hier ist das Ganze jetzt.

var conditions = {}; 

for (var key in req.query) { 
    if (req.query.hasOwnProperty(key)) { 
    conditions[key] = new RegExp('^' + req.query[key] + '$', 'i'); 
    } 
} 

var query = Character.find(conditions); 
query.exec(function(err, characters) { 
    if (err) throw err; 
    res.send({ characters: characters }); 
}); 
+0

Kein Problem, aber Sie sollten eine Antwort für zukünftige Benutzer auswählen, um zu wissen, welche Ihnen mehr geholfen hat. Wenn Sie nicht können, denken Sie darüber nach, Ihre eigene Antwort zu schreiben und diese als richtig zu prüfen. – cschaeffler

+1

Sie sollten Ihre Edit 2 entfernen und Ihre eigene Antwort schreiben, das ist toll btw –

+0

Sehr schön - funktioniert super; außer für den Hygieneteil mit der RegEx, der ungerade Abfragen erzeugt. – nottinhill

Antwort

10

Sie brauchen nicht Query#where wiederholt zu nennen, da man alle Bedingungen Mongoose Model#find als passieren kann:

var filteredQuery = {}, 
    acceptableFields = ['gender', 'race', /* etc */ ]; 

acceptableFields.forEach(function(field) { 
    req.query[field] && filteredQuery[field] = req.query[field]; 
}); 

var query = Character.find(filteredQuery); 

Sie haben auch req.query in Abhängigkeit von der zulässigen Parameter sanieren möchten, müssen Sie im Hinterkopf.

2

Nun,

würde ich so etwas wie dies empfehlen:

var query = Character.find() 
if(req.params.length < 0) { 
    for(var key in req.params) { 
    query.where(req.params[key]).equals(key); 
    } 
} else { 
    // do something without query params 
} 

dies nicht von mir getestet, aber es sollte funktionieren (vielleicht müssen Sie es ein wenig ändern, aber Sie bekommen die Idee). Bei dieser Lösung geht es nur darum, nicht zu überprüfen, was tatsächlich in den Parametern enthalten ist, also stellen Sie sicher, dass nur gutes Material in die for-Schleife kommt oder validiert wird, aber einige Regex- oder if-Anweisungen benötigen.

Hoffe das hilft dir.

+0

** Für zukünftige Besucher **: Das Beispiel der akzeptierten Antwort funktioniert nicht. Ich benutze nicht einmal req.params, sondern req.query. Anstatt ".where" zu verketten, baue ich ein * condition * -Objekt dynamisch und übergebe es dann an 'Character.find()'. Siehe meine Edit # 2. –

Verwandte Themen