복붙노트

[MONGODB] 어떻게 유성 문서 작업의 메시지 카운트 예는 무엇입니까?

MONGODB

어떻게 유성 문서 작업의 메시지 카운트 예는 무엇입니까?

그것이 어떻게 작동하는지 내가 관찰 할 수 있도록 문서에서이 예제 문제를 충분히 이해 음 ... 나는 등, 그것을 다른 방법의 무리를 실행 시도

어떻게 당신이에 가입합니까? 우리는이 일을하는 데 필요한 클라이언트 측 코드를 포함 할 수 있나요?

메시지 카운트라는 모음이 있습니까? 방은 메시지의 모음입니다? 우리는 예에서 컬렉션 정의를 포함 할 수 있습니다?

이에 대한 모든 팁은 좋은 것입니다!

참고 :이 질문에 처음 게시 된 때 (2012 년 5 월) 등장이 코드입니다. 지금은 간단합니다.

// server: publish the current size of a collection
Meteor.publish("messages-count", function (roomId) {
  var self = this;
  var uuid = Meteor.uuid();
  var count = 0;

  handle = Room.find({room_id: roomId}).observe({
    added: function (doc, idx) {
      count++;
      self.set("messages-count", uuid, "count", count);
      self.flush();
    },
    removed: function (doc, idx) {
      count--;
      self.set("messages-count", uuid, "count", count);
      self.flush();
    }
    // don't care about moved or changed
  });

  // remove data and turn off observe when client unsubs
  self.onStop(function () {
    handle.stop();
    self.unset("messages-count", uuid, "count");
    self.flush();
  });
});

해결법

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

    1.명확한 설명을 작성하는 나에게 메시지를 주셔서 감사합니다. 여기 내 의견 풀러 예입니다. 내가 정리 한 몇 가지 버그와 불일치가 있었다. 다음 문서 버전이 사용됩니다.

    명확한 설명을 작성하는 나에게 메시지를 주셔서 감사합니다. 여기 내 의견 풀러 예입니다. 내가 정리 한 몇 가지 버그와 불일치가 있었다. 다음 문서 버전이 사용됩니다.

    Meteor.publish은 매우 유연합니다. 클라이언트에 기존 MongoDB의 컬렉션을 게시 제한 아니에요 : 우리는 우리가 원하는 모든 것을 게시 할 수 있습니다. 특히, Meteor.publish는 클라이언트가 가입 할 수있는 문서의 집합을 정의합니다. 각 문서는 일부 컬렉션 이름 (문자열)에 속하는 고유의 _id 필드가 다음 JSON의 일부 속성 세트가 있습니다. 설정 변경의 문서로, 서버는 최신 클라이언트를 유지, 각각의 가입 된 클라이언트까지 변경 사항을 보내드립니다.

    우리는 "카운트"라는 이름의 컬렉션 하나의 문서를 포함하는 "카운트 별 방"이라는 여기에 문서 세트를 정의하는 것입니다. 이 문서는 두 개의 필드 것 : 객실의 ID와 roomId, 그리고 수 : 그 방에있는 총 메시지 수를. 카운트라는 이름의 실제 MongoDB의 수집이 없습니다. 이것은 우리의 유성 서버가 클라이언트에 내려 보내와 클라이언트 측 수집라는 이름의 카운트에 저장됩니다 컬렉션의 이름 만입니다.

    이렇게하려면, 우리의 기능은 클라이언트에서 올 것이다 roomId 매개 변수를 사용하고, 그 방에있는 모든 메시지 (다른 곳에서 정의)의 쿼리를 관찰 게시 할 수 있습니다. 우리는보다 효율적으로 observeChanges 우리는 새로운 하나를 추가 또는 삭제하는 것이 바로 지식을 전체 문서를 필요로하지 않으므로 여기에 쿼리를 관찰의 형태로 사용할 수 있습니다. 언제든지 새 메시지는 업데이트 된 총 클라이언트에 새 문서는 다음 발행 우리가 내부 카운트 우리의 콜백 단위로, 관심있는 roomId으로 추가하고있다. 메시지가 제거 될 때, 그것은 수를 감소하고 클라이언트에게 업데이트를 보냅니다.

    우리가 처음 observeChanges를 호출 할 때, 추가 콜백의 일부 수는 바로, 각 메시지에 대해 이미 존재한다는 것을 실행됩니다. 메시지가 추가되거나 제거 될 때마다 그리고 미래의 변화가 발생합니다.

    우리의 게시 기능은 청소하기 위해 중지시 핸들러를 등록 할 때 클라이언트 구독 취소 (수동 또는 분리에). 이 핸들러는 실행중인 observeChanges 아래로 클라이언트와 눈물의 속성을 제거합니다.

    각 클라이언트가 대신 실행하는 observeChanges있을 것이다 있도록 게시 기능은 "카운트별로 방"을 때마다 새로운 클라이언트 구독을 실행합니다.

    // server: publish the current size of a collection
    Meteor.publish("counts-by-room", function (roomId) {
      var self = this;
      var count = 0;
      var initializing = true;
    
      var handle = Messages.find({room_id: roomId}).observeChanges({
        added: function (doc, idx) {
          count++;
          if (!initializing)
            self.changed("counts", roomId, {count: count});  // "counts" is the published collection name
        },
        removed: function (doc, idx) {
          count--;
          self.changed("counts", roomId, {count: count});  // same published collection, "counts"
        }
        // don't care about moved or changed
      });
    
      initializing = false;
    
      // publish the initial count. `observeChanges` guaranteed not to return
      // until the initial set of `added` callbacks have run, so the `count`
      // variable is up to date.
      self.added("counts", roomId, {count: count});
    
      // and signal that the initial document set is now available on the client
      self.ready();
    
      // turn off observe when client unsubscribes
      self.onStop(function () {
        handle.stop();
      });
    });
    

    이제 클라이언트에서, 우리는 단지 일반적인 유성 가입처럼이 처리 할 수 ​​있습니다. 첫째, 우리는 우리의 계산 카운트 문서를 보유 할 Mongo.Collection이 필요합니다. 서버가 "계산"라는 이름의 모음으로 게시되어 있기 때문에, 우리는 Mongo.Collection 생성자에 인수로 "계산"을 전달합니다.

    // client: declare collection to hold count object
    Counts = new Mongo.Collection("counts");
    

    그럼 우리가 구독 할 수 있습니다. 구독의 이름은 "카운트별로 방"이며, 하나 개의 인수한다 : (넣어하는 장소가 될 때까지 유성 들어오는 업데이트를 큐에. 당신은 실제로 컬렉션을 선언하기 전에 구독 할 수 있습니다) : 현재의 룸의 ID를. 나는 Deps.autorun 안에이 포장했습니다 그래서에 Session.get ( 'roomId')가 변경으로 그 클라이언트 것이다 새로운 공간의 카운트 이전 룸의 수와 다시 구독에서 자동으로 구독 취소.

    // client: autosubscribe to the count for the current room
    Tracker.autorun(function () {
      Meteor.subscribe("counts-by-room", Session.get("roomId"));
    });
    

    마지막으로, 우리는 카운트에서 문서를 가지고 우리는 클라이언트의 다른 몽고 모음처럼 사용할 수 있습니다. 서버가 새로운 수를 보낼 때마다 참조는이 데이터가 자동으로 다시 그릴 것 모든 템플릿입니다.

    // client: use the new collection
    console.log("Current room has " + Counts.findOne().count + " messages.");
    
  2. ==============================

    2.레온 하르트 WILLE 말했듯이,이 솔루션의 단점은 유성은 단지 그들을 계산 몽고 서버에서 항목의 전체 컬렉션을 다운로드한다는 것입니다. gist.github.com/3925008에서 그의 해결책은 더 나은이지만, 새로운 항목을 삽입 할 때 카운터는 업데이트되지 않습니다.

    레온 하르트 WILLE 말했듯이,이 솔루션의 단점은 유성은 단지 그들을 계산 몽고 서버에서 항목의 전체 컬렉션을 다운로드한다는 것입니다. gist.github.com/3925008에서 그의 해결책은 더 나은이지만, 새로운 항목을 삽입 할 때 카운터는 업데이트되지 않습니다.

    여기 내 반응 솔루션입니다

    컬렉션 :

    Players = new Meteor.Collection("players");
    PlayersCounts = new Meteor.Collection("players_counts")
    

    섬기는 사람:

    Meteor.publish("players_counts", function(){
        var uuid = Meteor.uuid()
        var self = this;
    
        var unthrottled_setCount = function(){
            cnt = Players.find({}).count()
            self.set("players_counts", uuid, {count: cnt})
            self.flush()
        }
    
        var setCount = _.throttle(unthrottled_setCount, 50)
    
        var handle = Meteor._InvalidationCrossbar.listen({collection: "players"}, function(notification, complete){
            setCount();
            complete();
        })
    
        setCount();
        self.complete()
        self.flush()
    
        self.onStop(function(){
            handle.stop();
            self.unset("players_counts", uuid, ["count"]);
            self.flush();
        });
    });
    

    고객:

    Meteor.subscribe("players_counts")
    
    Template.leaderboard.total = function(){
        var cnt = PlayersCounts.findOne({})
        if(cnt) {
            return cnt.count;
        } else {
            return null;
        }
    }
    
  3. ==============================

    3.그냥 self.flush ()는 클라이언트에 업데이트의 수천을 보내는 문제에 대한 해결책을 발견 - 바로 사용 _.debounce을 할 때 계산 :

    그냥 self.flush ()는 클라이언트에 업데이트의 수천을 보내는 문제에 대한 해결책을 발견 - 바로 사용 _.debounce을 할 때 계산 :

    count = 0
    throttled_subscription = _.debounce =>
      @set 'items-count', uuid, count: count
      @flush()
    , 10
    handle = Items.find(selector).observe
      added: =>
        count++
        throttled_subscription()
      removed: =>
        count--
        throttled_subscription()
    

    이것은 단지 수를 설정하고 변화없이 10ms의 후 가입을 플래시합니다.

    힌트에 대한 #meteor에 @possibilities에게 감사드립니다.

  4. from https://stackoverflow.com/questions/10565654/how-does-the-messages-count-example-in-meteor-docs-work by cc-by-sa and MIT license