2013-10-30 25 views
7

次のコードはクエリーストリングまたはクエースストリングのみで動作します。つまり、単に/charactersに行くと、すべての文字が返されます。しかし、クエリーストリングのパラメータ/characters?gender=maleを指定すると、オスの文字だけが返されます。Mongooseで条件付きクエリを作成する方法は?

どのように私はこれはで動作するように拡張することができどちらか、2、、またはなしクエリ文字列? それぞれの場合に8または9の異なるif文を記述することを避けることをお勧めします。私はnullまたはundefinedの場合、Mongooseが単に$()を無視することを望んでいましたが、そうではありません(コメントアウトされたコードを参照)。

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); 
    }); 

編集: は、まあ、私は今のところ7 if文でそれを行うことができると思います。誰かがより洗練された解決策を見つけられない限り。

編集2:

みんなありがとう。皆さんが私がこの簡潔な解決策を達成するのを手助けしてくれたので、一つの答えを選ぶのは難しいです。ここに全体があります。また、あなたは持っている許可パラメータに応じreq.queryをサニタイズしたいと思う

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

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

var query = Character.find(filteredQuery); 

:としてあなたがMongoose Model#findにすべての条件を渡すことができますので、あなたは、繰り返しQuery#whereを呼び出す必要はありません

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

問題はありませんが、将来のユーザーがどのユーザーに役立ったかを知るための回答を選択する必要があります。あなたができない場合は、あなた自身の答えを書いて、それを正しいものとしてチェックすることを考えてください。 – cschaeffler

+1

あなたは編集2を削除し、あなた自身の答えを書くべきです、それは素晴らしいbtwです –

+0

非常にいいです - 素晴らしい作品;奇妙なクエリを生成するRegExの衛生部を除きます。 – nottinhill

答えて

10

念頭に置いて。 (多分あなたはそれを少し変更する必要がありますが、あなたのアイデアを得る)

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 
} 

これは私がテストされていませんが、それは動作するはずです:

2

まあ、

私はこのような何かをお勧めします。この解決策は、実際には何が実際にparamsにあるかをチェックしないことです。そのため、良いものだけが入ってくるか、forループのどこかで検証されますが、いくつかのregexやif文が必要です。

希望すると、これが役立ちます。

+0

**将来の訪問者に**:受け入れられる回答の例は機能しません。私はreq.paramsを使うのではなく、req.queryを使っています。 '.where'を連鎖させるのではなく、*条件*オブジェクトを動的に構築し、それを' Character.find() 'に渡します。私の編集#2を参照してください。 –

関連する問題