2015-01-25 12 views
0

나는 node.jsmongoose 라이브러리를 가지고 MongoDB를 사용 해왔다. node.js 응용 프로그램에 가장 적합한 솔루션을 어디에서 발견했기 때문에 MongoDB를 사용하기로 결정했습니다.몽고는 내 서비스를 취급합니까?

내 API의 응답 시간은 좋지만 MongoDB가 스케일링 할 때 MongoDB가 처리한다는 것은 확실하지 않습니다.

대부분의 쿼리로는 필요한 모든 데이터를 얻을 수 없다는 것을 알았 기 때문에 몇 가지 쿼리를 작성하고 일부 javascript map/reduce 함수를 사용합니다 (즉, 제가 두려워하는 것입니다) . 이 예에서

봐 :

var obj = this.toObject(); 
var deferred = new Promise(); 

Post 
.find({ idol : obj._id }) 
.lean() 
.exec(function(err, posts) 
{ 
    var postViews = 0; 
    var postLikes = 0; 
    var postShares = 0; 

    posts.reduce(function(prev, next) 
    { 
     postViews += next.views.length; 
     postLikes += next.likes.length; 
     postShares += next.shares.length; 
    }, 0); 

    obj.metas.postViews = postViews; 
    obj.metas.postLikes = postLikes; 
    obj.metas.postShares = postShares; 
    obj.metas.postCount = posts.length; 

    Subscription 
    .count({ idol : obj._id }, function(err, count) 
    { 
     obj.metas.subscribers = count; 

     deferred.deliver(obj); 
    }); 
}); 

reduce 함수를 사용

 User 
     .find({ 
      idol : true 
     }) 
     .sort({ 
      'metas.followers' : -1 
     }) 
     .select('-password -__v -posts -email') 
     .skip(offset) 
     .limit(30) 
     .exec(function(err, retData) 
     { 
      promisedIdols = retData.map(function(idol) 
      { 
       return idol.withStatistics(Post, Follow, req.user); 
      }); 

      idols = []; 

      if(promisedIdols.length == 0) 
      { 
       callback(); 
      } 

      for(var i=0; i<promisedIdols.length; i++) 
      { 
       promisedIdols[i].delegate(function(result) 
       { 
        idols.push(result); 

        if(idols.length == promisedIdols.length) 
        { 
         callback(); 
        } 
       }); 
      } 

     }); 

다음 코드를 실행 한 후 해결 될 것 promises의 배열을 수집하는 map을 사용했습니다 .

이 코드는 큰 규모로 잘 작동하지 않습니다. 데이터베이스를 재구성해야합니까? 데이터베이스 시스템을 변경해야합니까? 아마도 MongoDB를 잘못 사용하고 있을까요?

전문가들?

감사합니다.

+0

네이티브 배열 기능을 사용하면 데이터베이스가 증가함에 따라 문제가 발생할 것이라는 나의 발견이있었습니다. 하나의 솔루션 (방금 수행 한)은 비동기 모듈을 사용하는 것입니다. async.map/async.reduce는 원하는 것을 정확하게 제공 할 수 있지만 비 차단 방식으로 제공합니다. – TheIronDeveloper

+0

@TheIronDeveloper 예, 볼 수 있듯이 약속을 사용하고 있으므로 어쨌든 결과를 기다릴 필요가 있습니다 (자바 스크립트지도/축소가 실제로 느리다는 것을 알고 있습니다). –

답변

1

좋은 데이터 모델을 설정하면 몽고가 많이 처리 할 수 ​​있습니다. 규모를 조정할 때 염두에 두어야 할 몇 가지 사항이 있습니다.

데이터를 표준화하지 않도록하고 다른 컬렉션으로 나누십시오. 데이터 중복은 (때로는 현명하게 사용되는 경우) 친구가되면 더 간단한 쿼리를 작성하고 즉시 채울 수 있습니다. 예, 데이터를 업데이트 할 때 두 곳에서 업데이트해야하지만, Mongo는 비동기 적으로 (약속 여부와 상관없이) 많은 기록을 남깁니다.

특정 쿼리에는 전체 데이터 모델이 표시되지 않지만 어 그리 게이션 프레임 워크를 사용할 수는 있습니다. 그 파이프 라인은 네이티브 (C++, mapReduce JavaScript에 opossed 됨)로 정말 빠르게 작동합니다. 같은

뭔가 : 또한, 조건부 그룹,을 분류 할, 감는 많이 혼합 파이프 라인을 셔플 할 수

db.post.aggregate(
    // First $match to reduce the dataset 
    { 
    $match: {idol : obj._id} 
    }, 
    // then group and aggregate your data 
    { 
    $group: { 
     _id: '$idol', // group by that idol thing 
     postViews: {$sum: '$postViews'}, 
     postLikes: {$sum: '$postLikes'} 
    }, 
    }, 
    // Then use project to arrange the result the way you like it 
    { 
    $project: { 
     _id: false, //or true if you need it 
     metas: { 
      postViews: '$postViews' 
     }, 
     likeCountOfPosts: '$postLikes', // that's how you'd rename 
     whatIsIt: {$literal: 'a great post'} 
    } 
    } 
); 

.

Mongo mapReduce보다 훨씬 빠릅니다.

+0

감사합니다! 그래도지도/축소를 대체 할 수없는 경우도 있습니다. 나는 데이터 중복에 대한 귀하의 제안을 사용하고 있습니다. –