【问题标题】:Meteor: Speeding up MongoDB Join's for Big Data?Meteor:加速 MongoDB 加入大数据?
【发布时间】:2016-07-13 15:01:09
【问题描述】:

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

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

我一次查询了大约16行Data集合,目前Users集合中有18833个用户。

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

Mongo 收藏:

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

采集数据:

可以选择对我的收藏进行预处理,以便已经包含国家/地区,但是我不能修改这些收藏。我认为在服务器启动时完成此 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}}
    ])

【问题讨论】:

  • 将您的文档转储为文本.....
  • 我不允许使用我正在处理的项目的文本文档。
  • 聚合不针对 minimongo 运行,它只在服务器端运行。

标签: mongodb join meteor collections meteor-collections


【解决方案1】:

我会稍微不同地处理这个问题,使用reywood:publish-composite

  1. 在服务器上,我将使用 publish-composite 发布 glyphinfo,然后在发布中包含相关用户及其国家/地区字段
  2. 我会在需要显示国家名称和 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 }});
            }
        ]
    }
});

【讨论】:

  • 我成功地为#1 创建了发布,但是#2 需要太多的处理才能同时调用太多的 UserInfo.findOne(),它挂起我的浏览器。我正在尝试获取 peopleInfo 的国家/地区分布,以便我知道每个国家/地区有多少 Count 作为基于 peopleInfo 的数组。
  • #2 可能最好留给服务器上的 mongo-aggregation。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多