2013-10-30 34 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