我正在嘗試計算集合的子數組中的字段,並且我想每個月都這樣做。我曾在Mongo 2.6中工作,但最近升級到3.0.12在查詢中導致了一些錯誤的結果。它幾乎看起來像是沒有得到重置的幾個查詢。如何在MongoDB集合中分別累計幾個月的數據
因此,目前我正在做12個查詢異步並等待他們全部完成。這又是在2.6中工作。我的表結構是這樣的:
{
"_id" : ObjectId("<id>"),
"userId" : ObjectId("<id>"),
"accountId" : "1234567890",
"transactionId" : "22222222333",
"date" : ISODate("2016-09-08T04:00:00.000Z"),
"description" : "SUPERCOOL STORE",
"amount" : -123.45,
"allocations" : [
{
"jarId" : ObjectId("566faf1937af9ae11ef84bc4"),
"amount" : -100
},
{
"jarId" : ObjectId("566faf1937af9ae11ef84bc1"),
"amount" : -23.45
}
],
"reconciled" : true,
"tally" : true,
"split" : true
}
這是我的代碼:
var getTransactionAggregate = function (userId, month) {
var deferred = q.defer();
var nextMonth = moment(month).add(1, 'M');
Transactions.aggregate([
{$match: {
userId: userId,
tally: true,
date: {
$gte: month.toDate(),
$lt: nextMonth.toDate()
}
}},
{$project: { _id: 0, allocations: 1 } },
{$unwind: '$allocations'},
{$group: {_id: '$allocations.jarId', total: {$sum: '$allocations.amount'}}}
]).then(function(data) {
deferred.resolve(data);
})
.catch(function (err) {
logger.error(err);
deferred.reject(err);
});
return deferred.promise;
};
summaryReport = function (req, res) {
Jars.aggregate([
{ $match: {userId: new ObjectID(req.user._id)} },
{ $sort: {name: 1} }
])
.then(function (jars) {
var month = moment(moment().format('YYYY-MM') + '-01T00:00:00.000');
var i, j;
var promises = [];
for (i = 0; i < 12; i++) {
promises.push(getTransactionAggregate(new ObjectID(req.user._id), month));
month.add(-1, 'M');
}
q.allSettled(promises).then(function (data) {
for (i = 0; i < data.length; i++) {
// data[i].value here is returned incorrectly from the queries
........
});
});
};
所以基本上所發生的事情是第一個月包括正確的數據,但似乎總和繼續包括數據從前幾個月。如果我分解查詢,日期範圍內將返回正確的事務,並且展開也正常工作。正當這個羣體的步驟似乎是罪魁禍首。在我將Mongo升級到3.0.12之前,同樣的邏輯工作正常。
有沒有更好的方法來執行此查詢在一個鏡頭中或正在做十二個查詢的最佳方式?
感謝您的快速響應!你是對的,它必須與比賽有關,我只是把邏輯迴歸到第一原則,每月只有1件和總共3個月,第一個月的查詢返回所有三個項目,第二個月只返回2,上個月返回正確匹配的一個項目。 但是,按照您的建議改變匹配邏輯似乎沒有幫助。我也沒有把我所有的標準都放在$和$。 – Eric