gpt4 book ai didi

javascript - MeteorJS : why takes so long in foreach? 我应该使用 MongoDB 聚合操作,如何?

转载 作者:可可西里 更新时间:2023-11-01 09:14:02 26 4
gpt4 key购买 nike

我有一个集合,其中一个文档是这样的:

{
_id: 'string'
date: Date,
user: 'usera',
sections: [
{ heading: 'string a', score: 10 },
{ heading: 'string a', score: 104 },
{ heading: 'string b', score: 123 },
{ heading: 'string b', score: 15 },
{ heading: 'string b', score: 7 },
{ heading: 'string c', score: 1 }
]
totalScore: 259
}

该集合包含数十万个文档。

我需要按日期从集合中搜索并给出各部分的分数总和以及 totalScores 的总和。

如果我这样做,在 Meteor 出版物中

Meteor.publish('mydata', function() {
var rets = {}

Mycollections.find({date: {$gte: new Date(2016, 8, 1), $lt: new Date (2016, 12, 24)}}.forEach(function (doc) {
if (!rets[doc.user]) {
rets[doc.user] = {

tot: 0,
sections: {}
}
}

rets[doc.user].tot += doc.totalScore;
for (var i in doc.sections) {
if (!rets[doc.user].sections[doc.sections[i].heading]) {
sections[doc.sections[i].heading] = 0;
}

rets[doc.user].sections[doc.sections[i].heading] += sections[doc.sections[i].score;
}
});

return rets;

});

Mycollections.find({date: {$gte: new Date(2016, 8, 1), $lt: new Date (2016, 12, 24)}} 用时不到 0 毫秒执行。

对于单个 forEach 循环,执行大约需要 0-1 毫秒,如果我获取 20 000 个文档,则需要 20 秒来发布。

MongoDB 聚合在这里有何帮助?或者我如何更快地在服务器端执行计算?

我需要的是集合中每个用户的总分之和和每个部分的分数之和。

{
usera: {
tot: 235
sections[
{'string a': 200},
{'string b': 35},
{...}
]
},
userb: {
...
}

}

最佳答案

您可以执行聚合:

  • 符合您的日期范围
  • 计算每个用户的 totalScore
  • 计算每个部分的分数
  • user 分组并获得包含分数的部分数组

这可能由以下组成:

  • $match 您的日期范围
  • $group 计算totalScore 并将$$ROOT 文档推送到新字段以跟踪下一组
  • $unwind$$ROOT文件把数组转成json对象
  • $unwind sections 数组,每个部分记录一行(准备分组)
  • $groupuser 和按sections
  • 对所有部分得分求和
  • $group 将所有部分的得分重新组合为每个用户
  • 的一条记录

查询是:

db.document.aggregate([{
$match: {
date: {
$gte: ISODate("2016-08-01T00:00:00.0Z"),
$lte: ISODate("2016-12-24T23:59:00.0Z")
}
}
}, {
$group: {
_id: {
"user": "$user"
},
totalScore: { $sum: "$totalScore" },
document: { $push: "$$ROOT" }
}
}, {
$unwind: "$document"
}, {
$unwind: "$document.sections"
}, {
$group: {
_id: {
"user": "$_id.user",
"sections": "$document.sections.heading"
},
score: { $sum: "$document.sections.score" },
totalScore: { $first: "$totalScore" }
}
}, {
$group: {
_id: "$_id.user",
sections: { $push: { "name": "$_id.sections", "score": "$score" } },
totalScore: { $first: "$totalScore" }
}
}])

它给你类似的东西:

{ "_id" : "userc", "sections" : [ { "name" : "string c", "score" : 1 }, { "name" : "string b", "score" : 145 }, { "name" : "string a", "score" : 114 } ], "totalScore" : 259 }
{ "_id" : "usera", "sections" : [ { "name" : "string c", "score" : 12 }, { "name" : "string b", "score" : 1873 }, { "name" : "string a", "score" : 230 } ], "totalScore" : 269 }

在 Meteor 中,您可以执行聚合:

MyCollection.aggregate(
// aggregation query here
);

关于javascript - MeteorJS : why takes so long in foreach? 我应该使用 MongoDB 聚合操作,如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41316235/

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