3

コレクションを作りました

var Words = new Meteor.Collection("words");

そしてそれを公開しました:

Meteor.publish("words", function() {
    return Words.find();
});

クライアントでアクセスできるようにします。問題は、このコレクションが非常に大きくなり、その変換を公開したいということです。たとえば、"num words by length" という名前の要約を公開したいとします。これは int の配列で、インデックスは単語の長さ、項目はその長さの単語数です。そう

wordsByLength[5] = 12;

長さ 5 の単語が 12 個あることを意味します。SQL 用語では、元のデータ セットに対する単純な GROUP BY/COUNT です。クライアントで次のようなテンプレートを作成しようとしています

  • 長さ X の単語が N 個あります

長さごとに。私の質問は、「フォーム A のデータがあり、変換されたバージョン B を公開したい」ということになります。

4

3 に答える 3

21

更新次のように、サーバー上のコレクションを変換できます。

Words = new Mongo.Collection("collection_name"); 

Meteor.publish("yourRecordSet", function() {

  //Transform function
  var transform = function(doc) {
    doc.date = new Date();
    return doc;
  }

  var self = this;

  var observer = Words.find().observe({
      added: function (document) {
      self.added('collection_name', document._id, transform(document));
    },
    changed: function (newDocument, oldDocument) {
      self.changed('collection_name', oldDocument._id, transform(newDocument));
    },
    removed: function (oldDocument) {
      self.removed('collection_name', oldDocument._id);
    }
  });

  self.onStop(function () {
    observer.stop();
  });

  self.ready();

});
于 2013-08-20T20:42:22.253 に答える
1

他の回答で言及されている変換をラップするには、私が開発したパッケージmeteor-middlewareを使用できます。これには、プラグイン可能な優れた API が用意されています。したがって、変換を提供するだけでなく、それらを積み重ねることができます。これにより、コードの再利用、パーミッション チェック (パーミッションに基づくフィールドの削除または集約など) などが可能になります。したがって、必要な方法でドキュメントを集約できるクラスを作成できます。

ただし、特定のケースでは、 MongoDB 集計パイプラインを調べたい場合があります。本当にたくさんの単語がある場合、それらすべてを MongoDB サーバーから Meteor サーバー側に転送したくないでしょう。一方、集約パイプラインには、必要な反応性がありません。そのため、公開されたドキュメントの変更は、単語の出入りに応じてカウントされます。

私が開発した別のパッケージPeerDBを使用できることに対処するために。データの変更としてリアクティブに呼び出され、データベースに保存されるトリガーを指定できます。次に、通常の発行を使用して、カウントをクライアントに送信するだけです。欠点は、すべてのユーザーが同じコレクションに関心を持つ必要があることです。ユーザーごとではなく、グローバルに機能します。しかし、コレクション全体の単語数に関心がある場合は、(CoffeesScript で) 次のようにすることができます。

class WordCounts extends Document
  @Meta
    name: 'WordCounts'

class Words extends Document
  @Meta
    name: 'Words'
    triggers: =>
      countWords: @Trigger ['word'], (newDocument, oldDocument) ->
        # Document has been removed.
        if not newDocument._id
          WordCounts.update
            length: oldDocument.word.length
          ,
            $inc:
              count: -1
        # Document has been added.
        else if not oldDocument._id
          WordCounts.update
            length: newDocument.word.length
          ,
            $inc:
              count: 1
        # Word length has changed.
        else if newDocument.word.length isnt oldDocument.word.length
          WordCounts.update
            length: oldDocument.word.length
          ,
            $inc:
              count: -1
          WordCounts.update
            length: newDocument.word.length
          ,
            $inc:
              count: 1

そして、単純にWordCountsドキュメントを公開できます:

Meteor.publish 'counts', ->
  WordCounts.documents.find()
于 2015-02-08T00:28:29.577 に答える
0

Words で各ドキュメントを調べて、カウントを組み立てることができます (それぞれのカーソル) 。

var countingCursor = Words.find({});
var wordCounts = {};

countingCursor.forEach(function (word) {
  wordCounts[word.length].count += 1;
  wordCounts[word.length].words = wordCounts[word.length].words || []
  wordCounts[word.length].words.push(word);
});

ローカル コレクションを作成し、

var counts = new Meteor.Collection('local-counts-collection', {connection: null});

そしてあなたの答えを挿入してください

var key, value;

for (key in wordCounts) {
  value = object[key];
  counts.insert({
    length: key,
    count: value.count,
    members: value.words
  });
}

Counts はコレクションになりましたが、Mongo には保存されません。

未検証!

于 2013-08-23T06:57:19.663 に答える