복붙노트

[MONGODB] 유성의 평균 집계 쿼리

MONGODB

유성의 평균 집계 쿼리

좋아, 여전히 내 장난감 응용 프로그램에서, 나는 자동차 소유자 '거리계의 그룹에서 평균 주행 거리를 찾고 싶어요. 이 클라이언트에서 꽤 쉽지만 확장되지 않습니다. 권리? 그러나 서버에, 나는 정확히 그것을 수행하는 방법을 볼 수 없습니다.

질문 :

@HubertOG에 의한 제안은 의미가 Meteor.call을 사용하고 있었고, 난 이런 짓을 :

# Client side
Template.mileage.average_miles = ->
  answer = null
  Meteor.call "average_mileage", (error, result) ->
    console.log "got average mileage result #{result}"
    answer = result
  console.log "but wait, answer = #{answer}"
  answer

# Server side
Meteor.methods average_mileage: ->
  console.log "server mileage called"
  total = count = 0
  r = Mileage.find({}).forEach (mileage) ->
    total += mileage.mileage
    count += 1
  console.log "server about to return #{total / count}"
  total / count

그것은 잘 작동 것 같다,하지만 근처로 나는 Meteor.call 비동기 호출입니다 말할 수 없기 때문에 때문에 대답은 항상 null이 반환됩니다. 서버에서 물건을 취급 난 그냥 뭔가를 간과해야한다는 공통의 충분한 사용 사례처럼 보인다. 그 어떤 것입니까?

감사!

해결법

  1. ==============================

    1.그들에 라이브 업데이트를 할 수 없음 (간단한) 방법이 없기 때문에 유성 0.6.5로, 수집 API는 아직 집계 쿼리를 지원하지 않습니다. 결과가 정적 될 것입니다 그러나, 비록 당신은 여전히 ​​그들에게 직접 작성하고, Meteor.publish에서이를 사용할 수 있습니다. 여러 집계를 병합하고 클라이언트 측 콜렉션 API를 사용할 수 있기 때문에 제 생각에는, 이런 식으로 일을하는 것은 여전히 ​​바람직하다.

    그들에 라이브 업데이트를 할 수 없음 (간단한) 방법이 없기 때문에 유성 0.6.5로, 수집 API는 아직 집계 쿼리를 지원하지 않습니다. 결과가 정적 될 것입니다 그러나, 비록 당신은 여전히 ​​그들에게 직접 작성하고, Meteor.publish에서이를 사용할 수 있습니다. 여러 집계를 병합하고 클라이언트 측 콜렉션 API를 사용할 수 있기 때문에 제 생각에는, 이런 식으로 일을하는 것은 여전히 ​​바람직하다.

    Meteor.publish("someAggregation", function (args) {
        var sub = this;
        // This works for Meteor 0.6.5
        var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
    
        // Your arguments to Mongo's aggregation. Make these however you want.
        var pipeline = [
            { $match: doSomethingWith(args) },
            { $group: {
                _id: whatWeAreGroupingWith(args),
                count: { $sum: 1 }
            }}
        ];
    
        db.collection("server_collection_name").aggregate(        
            pipeline,
            // Need to wrap the callback so it gets called in a Fiber.
            Meteor.bindEnvironment(
                function(err, result) {
                    // Add each of the results to the subscription.
                    _.each(result, function(e) {
                        // Generate a random disposable id for aggregated documents
                        sub.added("client_collection_name", Random.id(), {
                            key: e._id.somethingOfInterest,                        
                            count: e.count
                        });
                    });
                    sub.ready();
                },
                function(error) {
                    Meteor._debug( "Error doing aggregation: " + error);
                }
            )
        );
    });
    

    위에서 / 카운트 응집 그룹화 한 예이다. 노트의 몇 가지 :

    당신이 이와 같은 출판물의 결과를 결합 시작하면, 당신은 신중하게 무작위로 생성 된 ID가 병합 상자에 미치는 영향을 고려해야합니다. 이 유성 API를 클라이언트 측에 사용하는 것이 더 편리 제외하고는 그러나이의 간단한 구현은, 단지 표준 데이터베이스 쿼리입니다.

    TL; DR 버전 : 거의 언제든지 서버에서 데이터를 밀고하는 게시 방법에 바람직하다.

    집계을이 게시물을 확인하는 다른 방법에 대한 자세한 내용은.

  2. ==============================

    2.나는 '집계'방법으로 이런 짓을. (0.7.x 버전)

    나는 '집계'방법으로 이런 짓을. (0.7.x 버전)

    if(Meteor.isServer){
    Future = Npm.require('fibers/future');
    Meteor.methods({
        'aggregate' : function(param){
            var fut = new Future();
            MongoInternals.defaultRemoteCollectionDriver().mongo._getCollection(param.collection).aggregate(param.pipe,function(err, result){
                fut.return(result);
            });
            return fut.wait();
        }
        ,'test':function(param){
            var _param = {
                pipe : [
                { $unwind:'$data' },
                { $match:{ 
                    'data.y':"2031",
                    'data.m':'01',
                    'data.d':'01'
                }},
                { $project : {
                    '_id':0
                    ,'project_id'               : "$project_id"
                    ,'idx'                      : "$data.idx"
                    ,'y'                        : '$data.y'
                    ,'m'                        : '$data.m'
                    ,'d'                        : '$data.d'
                }}
            ],
                collection:"yourCollection"
            }
            Meteor.call('aggregate',_param);
        }
    });
    

    }

  3. ==============================

    3.당신이 반응성을 원하는 경우에, Meteor.publish 대신 Meteor.call를 사용합니다. 그들이 (단지 this.userId에 대한 문서 위) 지정된 방에있는 메시지의 수를 게시 문서의 예를 들어 거기, 당신은 비슷한 일을 할 수 있어야합니다.

    당신이 반응성을 원하는 경우에, Meteor.publish 대신 Meteor.call를 사용합니다. 그들이 (단지 this.userId에 대한 문서 위) 지정된 방에있는 메시지의 수를 게시 문서의 예를 들어 거기, 당신은 비슷한 일을 할 수 있어야합니다.

  4. ==============================

    4.당신은 그것을 위해 Meteor.methods를 사용할 수 있습니다.

    당신은 그것을 위해 Meteor.methods를 사용할 수 있습니다.

    // server
    Meteor.methods({
      average: function() {
        ...
        return something;
      },
    
    });
    
    // client
    
    var _avg = {                      /* Create an object to store value and dependency */
      dep: new Deps.Dependency();
    };
    
    Template.mileage.rendered = function() {
      _avg.init = true;
    };
    
    Template.mileage.averageMiles = function() {
      _avg.dep.depend();              /* Make the function rerun when _avg.dep is touched */
      if(_avg.init) {                 /* Fetch the value from the server if not yet done */
        _avg.init = false; 
        Meteor.call('average', function(error, result) {
          _avg.val = result;
          _avg.dep.changed();         /* Rerun the helper */
        });
      }
      return _avg.val;
    });
    
  5. from https://stackoverflow.com/questions/18520567/average-aggregation-queries-in-meteor by cc-by-sa and MIT license