2016-07-12 4 views
1

データとユーザーの2つのコレクションがあります。データ収集には、約300〜800人のユーザーからなるユーザーIDの配列があります。Meteor:MongoDB Joinのビッグデータのスピードアップ?

データコレクション内の各行について、すべてのユーザーの国に参加する必要があります。これは、あまりにも多くのデータが一度にクエリされるため、Webブラウザがハングアップします。

私は、Dataコレクションの約16行を一度にクエリし、これまでUsersコレクションに18833人のユーザーが存在しています。

これまでのところ、Meteorメソッドと、Meteorコレクションのtransform()JOINの両方を作成しようとしましたが、これは私のアプリケーションを掛けているものです。

モンゴコレクション:

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

収集データ:

GlyphAllInOne Collection userInfo Collection

プレプロのオプションがあります

出版:サーバー方法テスト済み

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

私のコレクションを退治して、すでに国が含まれているようにしていますが、これらのコレクションを変更することはできません。私は、このJOINをサーバーの起動時に実行し、その後Meteorメソッドとして配列を介して公開すると、サーバーの起動時間が長くなりすぎる可能性があると推測します。私は確信していませんが。

誰でもこのクエリをスピードアップする方法はありますか?

EDIT: MongoDB集約コマンドも試しましたが、Meteorのミニゴンでは非常に遅いようです。ネイティブ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}} 
    ]) 
+0

文書をテキストでダンプする..... – profesor79

+0

私が取り組んでいるプロジェクトのテキストで文書を操作することはできません。 – Dranithix

+0

集約は、minimongoに対して実行されず、サーバー側のみを実行します。 –

答えて

0

は、データベース内のユニークの列をインデックスされ、待ち時間を解決する上で最大の要因で、巨大なMongoDBの集約コールを作成することによって、問題を解決しました。

私のデータベースに460万件以上のエントリを慎重に導入した後、Robomongoでは0.3秒、Meteor上でクライアントにデータを送信することで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; 
    } 
}); 

誰にも同様の問題に取り組んでいる場合は、私に連絡して自由に感じます。みなさん、お世話になりました。

0

私はパブリッシュ-複合使用してglyphinfoを公開して、出版 の関連ユーザーと自分の国フィールドが含まれるサーバーでreywood:publish-composite

  1. を使用して、少し異なるこの問題にアプローチでしょう
  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 }}); 
      } 
     ] 
    } 
}); 
+0

#1のためにパブリケーションを作成することができましたが、#2はブラウザをハングしたUserInfo.findOne()を同時に呼び出す処理が非常に必要でした。私はpeopleInfoの国分布を取得しようとしているので、peopleInfoに基づいた配列として、各国のCountの数がわかっています。 – Dranithix

+1

#2はおそらく、サーバー上のmongo-aggregationに残っているのがベストでしょう。 –

関連する問題