2016-05-12 82 views
1

我就快4的頂端爲路徑構建REST API可以說GET /api/users我想據此查詢我的用戶集合可選 queryParams。如何使用可選的快速查詢參數編寫Mongoose查詢?

因此對API的調用看起來是這樣的host:port/api/users?city=Berlin

在這種情況下name被省略,並且不影響查詢,而city必須匹配。

我設法做到這一點與以下黑客。有沒有比這更好的方法?

Users.statics.customFilter = function(qP){ 
    return this.find({ 
     $and: [ 
      {$or: [{undefined: {$eq: qP.city}}, {'city': qP.city}]}, 
      {$or: [{undefined: {$eq: qP.name}}, {'name': qP.name}]} 
     ] 
    }); 

mongoose.model('User', Users); 

我打電話從這樣的貓鼬架構這個靜態函數...

const User = mongoose.model('User'); 
app.get('/api/users', (req, res) => { 
     User.customFilter(req.query) 
     .exec((err, results) => { 
      if (err) return next(err); 
      res.json(results); 
     }); 
    }); 

回答

4

在我看來,這在本質上,User.find(req.query)應該做你想要什麼:

/api/users?city=Berlin   → User.find({ city : 'Berlin' }) 
/api/users?name=John    → User.find({ name : 'John' }) 
/api/users?name=John&city=Berlin → User.find({ city : 'Berlin', name : 'John' }) 

當然,你必須決定如果沒有參數被傳遞會發生什麼(在上面的例子中,它將成爲一個查詢,將墊ch 全部用戶,這可能不是你想要的)。

此外,您應該過濾req.query,以便它只包含您的架構中定義的字段。

+0

很酷,這是一個開始。但是,如果我不測試平等,也不會測試字符串。 因此 '{$或:[{undefined:{$ eq:qP.ageLower}},{'age':{$ gte:parseInt(qP.ageLower)}}]}' 不會工作這個權利? 另外我有我想要查詢的嵌套字段。所以queryParameter'city'應該實際測試'address.city'。有任何想法嗎? –

+0

如果您需要的不僅僅是簡單的相等性檢查,您將不得不處理傳入的數據,或者允許使用更復雜的查詢格式(['mongo-rql'](https://www.npmjs.com)/package/mongo-rql),['monquery'](https://www.npmjs.com/package/monquery),['mongo-querystring'](https://www.npmjs.com/package/mongo -請求參數))。 – robertklep