Meteor:加速 MongoDB 加入大数据?
Meteor: Speeding up MongoDB Join's for Big Data?
我有两个 collection:数据和用户。在数据 collection 中,有一个由大约 300 到 800 个用户组成的用户 ID 数组。
我需要为数据 collection 中的每一行连接所有用户的国家/地区,由于一次查询的数据太多,这使我的 Web 浏览器挂起。
我一次查询了大约 16 行数据 collection,并且到目前为止在用户 collection.
中还有 18833 个用户
到目前为止,我已经尝试为 Meteor 创建一个 Meteor 方法和一个 transform() JOIN collection,这就是挂起我的应用程序的原因。
Mongo Collection:
UserInfo = new Mongo.Collection("userInfo")
GlyphInfo = new Mongo.Collection("GlyphAllinOne", {
transform: function(doc) {
doc.peopleInfo = doc.peopleInfo.forEach(function(person) {
person.code3 = UserInfo.findOne({userId: person.name}).code3;
return person;
})
return doc;
}
});
'code3'指定用户所在国家。
出版物:
Meteor.publish("glyphInfo", function (courseId) {
this.unblock();
var query = {};
if (courseId) query.courseId = courseId;
return [GlyphInfo.find(query), UserInfo.find({})];
})
已测试的服务器方法:
Meteor.methods({
'glyph.countryDistribution': function(courseId) {
var query = {};
if (courseId) query.courseId = courseId;
var glyphs = _.map(_.pluck(GlyphInfo.find(query).fetch(), 'peopleInfo'), function(glyph) {
_.map(glyph, function(user) {
var data = Users.findOne({userId: user.name});
if (data) {
user.country = data ? data.code3 : null;
console.log(user.country)
return user;
}
});
return glyph;
});
return glyphs;
}
});
Collection数据:
有一个预处理我的 collection 的选项,这样国家就已经包括在内,但是我不允许修改这些 collection。我假设在服务器启动时完成此 JOIN,然后通过数组作为 Meteor 方法公开,可能会使服务器的启动时间延迟太久;虽然我不确定。
有人对如何加快此查询有任何想法吗?
编辑: 也尝试了 MongoDB 聚合命令,它在 Meteor 的 minimongo 上似乎非常慢。与本地 MongoDB 客户端上的 1 秒相比,查询需要 4 分钟。
var codes = GlyphInfo.aggregate([
{$unwind: "$peopleInfo"},
{$lookup: {
from: "users",
localField: "peopleInfo.name",
foreignField: "userId",
as: "details"
}
},
{$unwind: "$details"},
{$project: {"peopleInfo.Count": 1, "details.code3": 1}}
])
我会稍微不同地处理这个问题,使用 reywood:publish-composite
- 在服务器上,我会使用 publish-composite 发布字形信息,然后在发布中包含相关用户及其国家/地区字段
- 我会在需要显示国家名称和 glyphinfo 对象的任何地方在客户端加入国家
出版物:
Meteor.publishComposite('glyphInfo', function(courseId) {
this.unblock();
return {
find: function() {
var query = {};
if (courseId) query.courseId = courseId;
return GlyphInfo.find(query);
},
children: [
{
find: function(glyph) {
var nameArray = [];
glyph.person.forEach(function(person){
nameArray.push(person.name);
};
return UserInfo.find({ userId: {$in: nameArray }});
}
]
}
});
通过创建巨大的 MongoDB 聚合调用解决了问题,解决延迟的最大因素是索引数据库中的唯一列。
在我的包含超过 460 万个条目的数据库中仔细实施索引后,在 Robomongo 上花费了 0.3 秒,在 Meteor 上向客户端发送数据花费了 1.4 秒。
这里是聚合码,有兴趣的可以看看:
Meteor.methods({
'course.countryDistribution': function (courseId, videoId) {
var query = {};
if (courseId) query.courseId = courseId;
var data = GlyphInfo.aggregate([
{$unwind: "$peopleInfo"},
{$lookup: {
from: "users",
localField: "peopleInfo.name",
foreignField: "userId",
as: "details"
}
},
{$unwind: "$details"},
{$project: {"peopleInfo.Count": 1, "details.code3": 1}},
{$group: {_id: "$details.code3", count: {$sum: "$peopleInfo.Count"}}}
])
return data;
}
});
如果其他人正在处理类似问题,请随时与我联系。感谢大家的支持!
我有两个 collection:数据和用户。在数据 collection 中,有一个由大约 300 到 800 个用户组成的用户 ID 数组。
我需要为数据 collection 中的每一行连接所有用户的国家/地区,由于一次查询的数据太多,这使我的 Web 浏览器挂起。
我一次查询了大约 16 行数据 collection,并且到目前为止在用户 collection.
中还有 18833 个用户到目前为止,我已经尝试为 Meteor 创建一个 Meteor 方法和一个 transform() JOIN collection,这就是挂起我的应用程序的原因。
Mongo Collection:
UserInfo = new Mongo.Collection("userInfo")
GlyphInfo = new Mongo.Collection("GlyphAllinOne", {
transform: function(doc) {
doc.peopleInfo = doc.peopleInfo.forEach(function(person) {
person.code3 = UserInfo.findOne({userId: person.name}).code3;
return person;
})
return doc;
}
});
'code3'指定用户所在国家。
出版物:
Meteor.publish("glyphInfo", function (courseId) {
this.unblock();
var query = {};
if (courseId) query.courseId = courseId;
return [GlyphInfo.find(query), UserInfo.find({})];
})
已测试的服务器方法:
Meteor.methods({
'glyph.countryDistribution': function(courseId) {
var query = {};
if (courseId) query.courseId = courseId;
var glyphs = _.map(_.pluck(GlyphInfo.find(query).fetch(), 'peopleInfo'), function(glyph) {
_.map(glyph, function(user) {
var data = Users.findOne({userId: user.name});
if (data) {
user.country = data ? data.code3 : null;
console.log(user.country)
return user;
}
});
return glyph;
});
return glyphs;
}
});
Collection数据:
有一个预处理我的 collection 的选项,这样国家就已经包括在内,但是我不允许修改这些 collection。我假设在服务器启动时完成此 JOIN,然后通过数组作为 Meteor 方法公开,可能会使服务器的启动时间延迟太久;虽然我不确定。
有人对如何加快此查询有任何想法吗?
编辑: 也尝试了 MongoDB 聚合命令,它在 Meteor 的 minimongo 上似乎非常慢。与本地 MongoDB 客户端上的 1 秒相比,查询需要 4 分钟。
var codes = GlyphInfo.aggregate([
{$unwind: "$peopleInfo"},
{$lookup: {
from: "users",
localField: "peopleInfo.name",
foreignField: "userId",
as: "details"
}
},
{$unwind: "$details"},
{$project: {"peopleInfo.Count": 1, "details.code3": 1}}
])
我会稍微不同地处理这个问题,使用 reywood:publish-composite
- 在服务器上,我会使用 publish-composite 发布字形信息,然后在发布中包含相关用户及其国家/地区字段
- 我会在需要显示国家名称和 glyphinfo 对象的任何地方在客户端加入国家
出版物:
Meteor.publishComposite('glyphInfo', function(courseId) {
this.unblock();
return {
find: function() {
var query = {};
if (courseId) query.courseId = courseId;
return GlyphInfo.find(query);
},
children: [
{
find: function(glyph) {
var nameArray = [];
glyph.person.forEach(function(person){
nameArray.push(person.name);
};
return UserInfo.find({ userId: {$in: nameArray }});
}
]
}
});
通过创建巨大的 MongoDB 聚合调用解决了问题,解决延迟的最大因素是索引数据库中的唯一列。
在我的包含超过 460 万个条目的数据库中仔细实施索引后,在 Robomongo 上花费了 0.3 秒,在 Meteor 上向客户端发送数据花费了 1.4 秒。
这里是聚合码,有兴趣的可以看看:
Meteor.methods({
'course.countryDistribution': function (courseId, videoId) {
var query = {};
if (courseId) query.courseId = courseId;
var data = GlyphInfo.aggregate([
{$unwind: "$peopleInfo"},
{$lookup: {
from: "users",
localField: "peopleInfo.name",
foreignField: "userId",
as: "details"
}
},
{$unwind: "$details"},
{$project: {"peopleInfo.Count": 1, "details.code3": 1}},
{$group: {_id: "$details.code3", count: {$sum: "$peopleInfo.Count"}}}
])
return data;
}
});
如果其他人正在处理类似问题,请随时与我联系。感谢大家的支持!