2015-12-01 166 views
1

我有一個數據過濾表單,其中包含大約15到20下拉字段。下拉字段的目的是提供數據過濾選項。例如看看下面的圖像(圖像是從Zoopla應用):MongoDB查詢 - 數據過濾

enter image description here

正如你可以在圖片中看到,它顯示7個下拉領域。用戶爲每個字段選擇一個選項,或者只選擇幾個字段並在搜索按鈕上點擊,並顯示結果。

我想實現相同的功能,但那裏有一個問題。

我至今嘗試過!

用戶有權選擇是否填寫所有的下拉字段或者只是2,仍然可以搜索到。搜索功能非常流暢。用戶只能選擇ONE下拉字段,並將其餘的空餘字段仍然可以得到結果。

要實現這一點,我在我的API創建以下路線。

app.get('/user/test',function(req, res) { 

User.find({"$or": [{"employeeName": req.body.employeeName}, {"sector": {$elemMatch:{sec: req.body.sec}}} ] }, function(err, user) 
{ 
    if (err) 
     { 
     res.send(err); 
     } 
     console.log(user); 
     res.json(user); 

    }); 
    }); 

正如你可以看到我現在用的是$或獲取數據back.The問題是,如果用戶只填寫兩個employeeName和扇區參數並搜索它發回的所有數據匹配employeeName或匹配扇區。實際上,我只想要匹配兩個參數的數據。然後,我嘗試使用$和,這解決了問題,但現在用戶不能僅搜索employeeName或單個扇區等單個參數。它必須有兩個參數才能返回數據。

總之我如何編輯我的API我的搜索路徑給用戶以任何方式與任何數量的參數搜索的靈活性。只是要清楚,搜索只會發生在頁面的下拉字段內。因此,如果有20個下拉領域則用戶的是可能性,能夠搜索用最少的1個參數,最多20個參數

這是一個有點困難,我瞭解我的點所以,如果你不明白的問題,請讓我知道,我會盡力解釋再次

+0

構建一個查詢構建器,這將是一個更好的選擇 –

+0

@SarathNair感謝您的答覆。你能再解釋一下嗎?或者如果你有任何資源?我不確定查詢構建器的含義。 – Skywalker

+0

基本上你需要測試給定哪些參數,然後根據一系列預定義的查詢選擇相應的查詢或者(不確定這裏是否是適當的選擇)。查詢構建器基本上是Query對象的接口,其中每個方法都會返回查詢對象,以便您可以動態添加標準。我會告訴你如何去做,因爲我的JS太可怕了。 –

回答

0

我可以給你我是如何建立查詢的例子。我在SOA項目中的許多小型服務中使用它。通常我在控制器中檢查params是否根據我正在等待的類型進行驗證(如果您不使用像Mongoose這樣的orm),那麼我會在模型中構建查詢。 無論如何,我希望這會幫助你。

app.get('/user/test',function(req, res) { 
    // You initialize your mongodb query 
    var query = {}; 

    // If employeeName was set, then you update the query 
    if (req.body.employeeName){ 
     query.employeeName = req.body.employeeName; 
    } 

    // Same for the sector 
    if (req.body.sec){ 
     query.sector = {$elemMatch:{sec: req.body.sec}; 
    } 
    // and you keep going for every paramaters... 
    // Then you find with the query, if no parameter query = {} 
    User.find(query, function(err, users){ 
     if (err){ 
      res.send(err); 
     } 
     console.log(users); 
     res.json(users); 
    }); 
}); 

我也看到你想要的結果進行排序,所以你可能需要使用aggregate查詢來妥善處理這一點。 而對於「最近期]」你可以使用_id嵌入式時間戳:

ObjectId("564afd0b65d680ff47ccfc59").getTimestamp(); 
// =>ISODate("2015-11-17T10:10:19Z") 

//And in a shorter way: 
db.collection.find(query).sort({_id:-1}) 

//Inside an aggregate it gives: 
[{$sort: {_id: -1}}] 
+0

非常感謝你的回答。它確實有幫助。我會馬上執行並檢查。我只是有一個問題,通過使用你的方法,如果用戶發送一個HTTP調用5個或更多的參數,它仍然會檢查所有5個參數,並返回一個匹配所有5個參數查詢的結果?或者它一次只能處理一個參數? – Skywalker

+0

您必須自行編碼檢查,並且如果您收到此參數,則需要設置隨附的查詢。 在上面的例子中,我只處理2個參數(employeeName和sec)。 如果您想要處理價格,您必須檢查請求中是否存在第一個參數(req.body.price),然後您需要根據您想要對此參數執行的操作更新您的查詢。 – Metux