gpt4 book ai didi

mongodb - 如何在 Meteor 服务器端做 mongo 组

转载 作者:IT老高 更新时间:2023-10-28 12:28:57 26 4
gpt4 key购买 nike

meteor mongo shell 上我可以使用 db.collection.group 但从 Meteor.methods 我可以,因为 Meteor 不支持它。

我怎么能写一个方法来做类似的事情:

db.orders.group({
keyf: function(doc) {return {year:doc.createdAt.toISOString().substring(0, 4)}},
initial: {months:{}},
reduce: function(order, result) {
var month = order.createdAt.getMonth()+1,
date = order.createdAt.getDate();

month = result.months[month] || (result.months[month] = {});
date = month[date] || (month[date] = []);
date.push(order);
},
cond: {$and: [{createdAt: {$gt: new Date("2015-01-01")}, createdAt: {$lt: new Date("2015-12-31")}}]}
})

预期结果是按月份分组的对象数组,然后按月份内的日期分组。

附: orders,是相当大的集合,我真的很想在数据库中进行分组。


在获得有关 1.0.4 中 rawCollection() 的信息后,我尝试了以下操作:

  collection = Orders.rawCollection();
params = {
keyf: function(doc) {return {year:doc.createdAt.toISOString().substring(0, 4)}},
initial: {months:{}},
reduce: function(order, result) {
var month = order.createdAt.getMonth()+1,
date = order.createdAt.getDate();

month = result.months[month] || (result.months[month] = {});
date = month[date] || (month[date] = []);
date.push(order);
},
cond: {$and: [{createdAt: {$gt: new Date("2015-01-01")}, createdAt: {$lt: new Date("2015-12-31")}}]}
};
Meteor.wrapAsync(collection.group, collection)(params);

我明白了:

W20150327-13:26:24.924(2)? (STDERR) /Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/connection/base.js:246
W20150327-13:26:24.924(2)? (STDERR) throw message;
W20150327-13:26:24.924(2)? (STDERR) ^
W20150327-13:26:24.929(2)? (STDERR) TypeError: undefined is not a function
W20150327-13:26:24.929(2)? (STDERR) at /Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/collection/aggregation.js:229:22
W20150327-13:26:24.931(2)? (STDERR) at /Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/db.js:1191:22
W20150327-13:26:24.931(2)? (STDERR) at /Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/db.js:1903:9
W20150327-13:26:24.931(2)? (STDERR) at [object Object].Base._callHandler (/Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/connection/base.js:453:41)
W20150327-13:26:24.932(2)? (STDERR) at /Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/db.js:1758:29
W20150327-13:26:24.932(2)? (STDERR) at [object Object].Connection.write (/Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/connection/connection.js:272:16)
W20150327-13:26:24.932(2)? (STDERR) at __executeQueryCommand (/Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/db.js:1752:16)
W20150327-13:26:24.932(2)? (STDERR) at Db._executeQueryCommand (/Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/db.js:1902:7)
W20150327-13:26:24.933(2)? (STDERR) at Db.command (/Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/db.js:1183:8)
W20150327-13:26:24.933(2)? (STDERR) at Collection.group (/Users/jaro/.meteor/packages/mongo/.1.1.0.1jqg8g6++os+web.browser+web.cordova/npm/node_modules/mongodb/lib/mongodb/collection/aggregation.js:228:13)
=> Exited with code: 8

最佳答案

从 Meteor v1.0.4 开始:

Provide direct access to the collection and database objects from the npm Mongo driver via new rawCollection and rawDatabase methods on Mongo.Collection

所以你可以调用 collection.rawCollection() 来获取底层的集合对象:

var rawCollection = Orders.rawCollection();

这个 rawCollection 有一个方法 group 相当于 MongoDB shell 中的 group 方法。但是,底层节点 API 是异步的,因此您需要以某种方式将其转换为同步函数。我们不能直接使用 Meteor.wrapAsync 因为 group 接受不是主要回调的函数参数,所以我们将使用包装器解决这个问题:

function ordersGroup(/* arguments */) {
var args = _.toArray(arguments);
return Meteor.wrapAsync(function (callback) {
rawCollection.group.apply(rawCollection, args.concat([callback]));
})();
}

在您的方法中,您可以像在 Mongo shell 中调用 db.orders.group 一样调用 ordersGroup。但是,参数是单独传递的,而不是在一个对象中:

ordersGroup(keys, condition, initial, reduce[, finalize[, command[, options]]])

有关详细信息,请参阅 this documentation (尽管请注意 callback 参数应该被省略,因为我们的异步包装会处理这一点)。

所以你必须单独传递它们:

var result = ordersGroup(
// keys
function(doc) {
return { year: doc.createdAt.toISOString().substring(0, 4) };
},

// condition
{createdAt: {$lt: new Date("2015-12-31"), $gt: new Date("2015-01-01")}},

// initial
{months: {}},

// reduce
function(order, result) {
var month = order.createdAt.getMonth()+1,
date = order.createdAt.getDate();

month = result.months[month] || (result.months[month] = {});
date = month[date] || (month[date] = []);
date.push(order);
}
);

当然,这仅适用于服务器,因此请确保您的方法在仅服务器代码中(最好在 server 子目录中,或在 if (Meteor.isServer) 中)。

关于mongodb - 如何在 Meteor 服务器端做 mongo 组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29295143/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com