Mongodb &引用;分组方式;关于流星收集的疑问

Mongodb &引用;分组方式;关于流星收集的疑问,mongodb,meteor,aggregation-framework,Mongodb,Meteor,Aggregation Framework,我的数据mongoDB: >db.CUSTOMER.find() {"Name": "A", "CreatedDate": "Wed Jan 29 2014"} {"Name": "B", "CreatedDate": "Fri Jan 31 2014"} {"Name": "C", "CreatedDate": "Sat Feb 01 2014"} {"Name": "D", "CreatedDate": "Sat Feb 01 2014"} 在《流星》中: Customer

我的数据
mongoDB

>db.CUSTOMER.find()

{"Name": "A", "CreatedDate": "Wed Jan 29 2014"}

{"Name": "B", "CreatedDate": "Fri Jan 31 2014"}

{"Name": "C", "CreatedDate": "Sat Feb 01 2014"}

{"Name": "D", "CreatedDate": "Sat Feb 01 2014"}
在《流星》中:

Customer = new Meteor.Collection("CUSTOMER");
我试图在流星收集中按日期(星期一、星期二、星期三……)和总数据对它们进行分组。应该是这样的:

{"Date": "Wed Jan 29 2014", "Total" 1}

{"Date": "Fri Jan 31 2014", "Total" 1}

{"Date": "Sat Feb 01 2014", "Total" 2}
在mongoDB中,我只想使用它,但显然,它在meteor中是不可能的,因为它不支持findAndModify、upsert、aggregate函数和map/reduce

我可以做一些变通的例子来让它工作吗


谢谢

您需要手动将它们分组。有很多方法可以做到这一点,但这里有一个(公认难以理解的)例子:

var customers=Customer.find().fetch();
var groupedDates=u.groupBy(u.pull(客户,'CreatedDate'));
_.each(uu.value(groupedDates)、函数(日期){
log({Date:dates[0],Total:dates.length});
});

我想添加评论,但我的声誉太低了。 只需使用ux。countBy可能更具可读性

\uu.countBy(客户,函数(客户){return customer.CreatedDate})
这将返回一个dict([CreatedDate]:count)


希望这有助于

您可以使用meteor的这些功能,您正在谈论的,或者找到一个链接来描述客户端处理,但是从服务器端它是不同的

在大多数情况下,您应该使用而不是mapReduce或group函数。整个管道是用C++实现的,而不是传递到JavaScript引擎上。在所有情况下,聚合管道中的等效函数都会更快

> db.dates.aggregate([
    {$group: { _id: {$dayOfWeek: "$CreatedDate"}, Total: {$sum: 1} }},
    {$project: { _id: 0, day: "$_id", Total: 1 } },
    {$sort: { day: 1 }}
  ])


  {
    "result" : [
            {
                    "Total" : 1,
                    "day" : 4
            },
            {
                    "Total" : 1,
                    "day" : 6
            },
            {
                    "Total" : 2,
                    "day" : 7
            }
    ],
    "ok" : 1
  }
关于流星支援 服务器端,meteor使用驱动程序进行所有处理。它由MongoDB维护,并维护所有功能

客户端是一个称为“mini mongo”的库。这实际上不是一个驱动程序,而是一个小层,它实际上使用套接字连接将详细信息传递给服务器。它使客户端javascript“看起来”与服务器端代码相同,但实际上并不是直接与mongo对话


使用“发布”到
客户端的服务器端函数调用
服务器端的自定义代码没有什么错。如前所述,它只是您可以在其他nodejs应用程序中使用的标准驱动程序。

补充上述响应:

  • 您不能在客户端上使用所有mongo函数,因为meteor依赖于只实现mongo函数子集的
    mini mongo
    ,效率不高。因此,在客户端上,最好的选择是使用@david weldon所描述的一些下划线函数。据我所知,mini mongo也是一组下划线函数,并且是ID上唯一的索引
  • 您仍然可以使用服务器上的所有mongo函数,但这会让人感觉有点不舒服,因为Meteor试图将它们隐藏在包装后面。不过,这可能更有效。下面是它的样子:


这很好,但您也失去了Meteor通过
Customer.find(…).fetch()
提供的同步语法。现在,您可以将mongo聚合封装在Promise中,如果您想恢复该语法,可以使用wait/async。

您提到的meteor支持的缺乏是来自浏览器的客户端。您可以在服务器端执行操作。查看答案。到目前为止,我无法获取或打印该值。关于如何获取数据有什么建议吗?
var dict=u.countBy(客户,函数(客户){return customer.CreatedDate});Object.keys(dict).forEach(function(key){console.log(“key”,key,“count”,dict[key])})
谢谢,它工作得很好。这引出了另一个问题:这个答案似乎是基于CreatedDate的差异对数据进行分组的。如果我想每周、每月或每年(例如)对其进行分组,是否可能?当然,您可以只为like
函数(date){return date.split()[1];}
(假设您的日期是字符串-根据需要修改日期对象)。另外,请注意Flying Fisher的回答和countBy的想法相同。这个解决方案不是很慢吗?您是否建议将整个集合订阅到客户端,然后再执行u.groupBy?请记住,一旦返回数组,就失去了直接迭代光标的好处:每次数据更改时,整个模板都会重新呈现,而不仅仅是更改的数据。如果在模板中显示大量数据,则需要查询级聚合
mongoCustomer = Customer._collection.rawCollection() // you're now on the mongo realm

mongoCustomer.aggregate([
  {
    $group: {
      _id: "$CreatedDate",
      Total: { $sum: 1 }
    }
  }
], function(err, agg) {
  if (err) {
    ...
    return;
  }
  // agg an array of { CreatedDate, Total }, do what you want with it
});