2013-10-30 36 views
0

我使用Node/Express/MongoDB/Mongoskin構建應用程序。MongoDB查詢標準和預測

我的數據庫中有一個名爲「clients」的集合,其中包含有關客戶端帳戶信息的文檔。每個客戶端的文件包含一個包含發票對象的數組,像這樣:

doc.invoices = [ 
    {year: 2012, 
    quarter: 1, 
    daily: 912.00, 
    sms: 42.00, 
    paid: true}, 

    {year: 2012, 
    quarter: 2, 
    daily: 913.00, 
    sms: 55.00, 
    paid: true}, 

    {year: 2012, 
    quarter: 3, 
    daily: 876.00, 
    sms: 82.00, 
    paid: true}, 

    {year: 2012, 
    quarter: 4, 
    daily: 903.00, 
    sms: 93.00, 
    paid: false}, 

    {year: 2013, 
    quarter: 1, 
    daily: 915.00, 
    sms: 67.00, 
    paid: true}, 

    {year: 2013, 
    quarter: 2, 
    daily: 920.00, 
    sms: 35.00, 
    paid: true}, 

    {year: 2013, 
    quarter: 3, 
    daily: 880.00, 
    sms: 92.00, 
    paid: true}, 

    {year: 2013, 
    quarter: 4, 
    daily: 900.00, 
    sms: 85.00, 
    paid: false} 
] 

問:可以說,我想從這個集合查詢中的所有文件,就像在展示所有客戶端超級管理員 - 的觀點,但我希望將從發票數組返回的信息限制爲「年」等於某個值的對象,例如2013年,當年。

我想預測什麼是我需要的,但問題是,投影只返回找到的第一個結果......

+1

查看''unwind'運算符使用'aggregate'而不是'find'。 – JohnnyHK

+0

您的查詢是什麼樣的? –

回答

5

首先,投影不返回第一個結果,它發現它告訴mongo要返回什麼。

.findOne(query)將LIMIT結果賦給一個或查找(query).limit(1)也會做同樣的事情。

你說你試圖「獲取所有」你的數據。

標準查找類型的查詢會得到你的開始......

find({mongo:query},{mongo:projection}) 

但結果限制從蒙戈外殼*

,因爲你說用express.js你可以使用你的光標javascript函數由第一路線設定到​​一個功能「返回所有」一個簡單的查找結果像這樣的......

db.sales.find({"year":2013},{_id:0,"year":1,"quarter":1,"daily":1,"sms":1,"paid":1}) 

app.get('/sales/yr/:yr', sales.getAllResults); 

然後一個函數來處理你簡單的mongo查詢和投影。

/** 
* get ALL results given YEAR ONLY 
* extend jsonQuery to modify results 
* extend or reduce jsonProjection to control data returned 
*/ 
exports.getAllResults= function(req, res) { 
    var yr = req.params.yr ;  
    var jsonQuery = {"year":yr} ; //add or remove comma seperated "key":values given your JSON collection 
    var jsonProjection = {_id:0,"year":1,"quarter":1,"daily":1,"sms":1,"paid":1} ; //leave year out since that's specified in the query anyhow 
    var jsort = {"some-thing-else":-1} ; //-1 descending or 1 ascending 
    db.collection("YOUR-COLLECTION_NAME", function(err, collection) { 
     collection.find(jsonQuery, jsonProjection).sort(jsort).toArray(function(err, items) { 
      res.send(items); 
     }); 
    }); 
} 

最後你可能要遵循明確的教程和蒙戈也有一些好的,我把這個答案一起基於從克里斯Coenraets一個很好的起動看到: -

http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/

  • 使用標準的mongo查詢shell,默認情況下,您僅限於分頁結果集,其中鍵入「it」將遍歷結果。
0

不知道如果我的理解:

find({year:2013},function(err,clients){}) 

這將返回這一年等於2013的所有客戶端,它會返回所有文檔場

你談論的是用於限制查詢返回的字段中的投影,我的意思是:

find({year:2013},{year:1,paid:1},function(err,clients){}) 

其中一年是2013年和每個對象都將獲得2場(付費和年)

在此將返回對象的數組「{年:1,支付:1}」的對象是你的投影機。

0

由於@JohnnyK在他的評論中提到的,你應該使用MongoDB的aggregation framework

db.clients.aggregate([ 
    { $unwind: "$invoices" }, 
    { $match: { "invoices.year": 2013 } }, 
    { $group: { _id: "$_id", /* other client fields */, invoices: { $push: "$invoices" } } } 
]); 

在一你放鬆初始invoices陣列,然後只保留髮票與指定的年份和組匹配的發票到由客戶端領域陣列到底。

1

請記住,預測允許我們明確包含或排除MongoDB查詢中的字段。我們使用1來表示我們希望包含一個字段,並且0表示我們希望排除該字段。請記住,_id場是特別的 -

  • _id場被默認包含的,除非我們明確地排除它
  • 所有其他字段被排除在外,直到我們明確將它們納入

而且,由於我們」重新在javascript中工作,我們可以以與mongo shell中的方式非常相似的方式構建我們的項目文檔和文檔,以插入到我們的集合中。驅動程序提供了一組用於與MongoDB交互的類和方法,mongo shell提供了它自己的API。

W. r。噸。 CRUD截至MongoDB 3.2驅動程序和mongo外殼遵循相同的規格。從mongo外殼中訪問這些方法的方式以及實現方式各不相同。

 


var MongoClient = require('mongodb').MongoClient, 
    assert = require('assert'); 


MongoClient.connect('mongodb://localhost:27017/crunchbase', function(err, db) { 

    assert.equal(err, null); 
    console.log("Successfully connected to MongoDB."); 

    var query = {"category_code": "biotech"}; 
    var projection = {"name": 1, "category_code": 1, "_id": 0}; 

    var cursor = db.collection('companies').find(query); 
    cursor.project(projection); 

    cursor.forEach(
     function(doc) { 
      console.log(doc.name + " is a " + doc.category_code + " company."); 
      console.log(doc); 
     }, 
     function(err) { 
      assert.equal(err, null); 
      return db.close(); 
     } 
    ); 

}); 

 

node.js司機目前的最佳實踐,是鏈project打電話到我們cursorcursor.project。此項目調用會爲查詢設置字段投影。這個調用不會強制請求從數據庫中檢索文檔,就像foreach方法一樣。而是爲我們的cursor維護的查詢表示添加了一些額外的細節。有許多遊標方法,我們可以將它們連接在一起,以充分表達我們希望針對我們的數據庫執行的操作。撥打db.collection是同步的。我們將在這裏使用光標上的project方法修改cursor的字段projection