流星:加速MongoDB加入大数据?

时间:2016-07-12 07:09:30

标签: mongodb join meteor collections meteor-collections

我有两个集合:数据和用户。在数据集合中,有一组用户ID,包含大约300到800个用户。

我需要将数据集合中每一行的所有用户的国家/地区联系在一起,这会挂起我的网络浏览器,因为一次查询的数据太多。

我一次查询大约16行数据集合,目前在Users集合中还有18833位用户。

到目前为止,我已经尝试为Meteor集合制作Meteor方法和transform()JOIN,这是我的应用程序挂起的。

Mongo Collection:

db <- dbConnect(MySQL(),mysql.user)

&#39; CODE3&#39;指定用户的国家/地区。

公开:

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;
    }
});

经测试的服务器方法:

Meteor.publish("glyphInfo", function (courseId) {
    this.unblock();
    var query = {};
    if (courseId) query.courseId = courseId;
    return [GlyphInfo.find(query), UserInfo.find({})];
})

收集数据:

GlyphAllInOne Collection userInfo Collection

可以选择预处理我的收藏集,以便已经包含国家/地区,但我不允许修改这些收藏集。我假设在服务器启动时进行此JOIN,然后通过数组作为Meteor方法公开,可能会延长服务器的启动时间太长时间;虽然我不确定。

有没有人对如何加快此查询有任何想法?

编辑:也尝试了MongoDB聚合命令,它在Meteor的minimongo上看起来非常慢。在本机MongoDB客户端上进行4分钟查询与1秒相比。

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;
    }
});

2 个答案:

答案 0 :(得分:0)

我会使用reywood:publish-composite

稍微改变一下这个问题
  1. 在服务器上,我将使用publish-composite发布glyphinfo,然后在出版物中包含相关用户及其国家/地区字段
  2. 无论我需要在哪里显示国家名称以及glyphinfo对象,我都会在客户端加入国家
  3. 公开:

    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 }});
                }
            ]
        }
    });
    

答案 1 :(得分:0)

通过创建一个巨大的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;
    }
});

如果其他人正在处理类似问题,请随时与我联系。谢谢大家的支持!