1

サーバー上にカスタム パブリケーションがあります (何らかの方法で 2 つのコレクションに参加しています)。

このパブリケーションの結果のセットはまさに私が必要としているものですが、パフォーマンスの問題のため、クライアントに完全に送信することは避けたいと思います.

パフォーマンスを気にしなければ、出版物を購読して、次のようなことをするだけです theCollection.find({"my":"filter"})

したがって、サーバー側のカスタム パブリケーションにフィルターが適用されるように、カスタム パブリケーションのサブセットをパブリッシュする方法を見つけようとしています。

パブリケーションをチェーンまたはフィルタリングする方法はありますか (サーバー側)?

質問については、カスタム パブリケーションが次のようになり、変更できないと想定できます。

Meteor.publish('customPublication', function() {
    var sub = this;

    var aCursor = Resources.find({type: 'someFilter'});
    Mongo.Collection._publishCursor(aCursor, sub, 'customPublication');

    sub.ready();
  });
4

2 に答える 2

1

私が質問を正しく理解している場合、あなたはhttps://atmospherejs.com/reywood/publish-compositeを探しています

「リアクティブ結合を使用して、さまざまなコレクションから一連の関連ドキュメントを公開できます。これにより、ドキュメントのツリー全体を一度に簡単に公開できます。公開されたコレクションはリアクティブであり、追加/変更/削除が行われると更新されます。」

于 2015-06-04T03:11:28.477 に答える
0

OK、次の回避策にたどり着きました。出版物に取り組む代わりに、他のコレクションに従って更新する新しいコレクションを追加しただけです。そうするために、流星フックパッケージを使用しています

function transformDocument(doc)
{
doc.aField = "aValue"; // do what you want here
return doc;
}

ACollection.after.insert(function(userId, doc)
{
    var transformedDocument = transformDocument(doc);
    AnotherCollection.insert(transformedDocument);
});

ACollection.after.update(function(userId, doc, fieldNames, modifier, options)
{
    var transformedDocument = transformDocument(doc);
    delete transformedDocument._id;
    AnotherCollection.update(doc._id,{$set:transformedDocument});
});

ACollection.after.remove(function(userId, doc)
{
    AnotherCollection.remove(doc._id);
});

次に、通常の方法でサブセットを公開できる新しいコレクションがあります

利点:

  • このデータベースに必要なものは何でもフィルタリングできます。フィールドが仮想か実在かを心配する必要はありません
  • データベースが変更されるたびに 1 つの操作のみ。これにより、複数の出版物が同じデータをマージすることを回避できます

洞窟は食べる:

  • これには、もう1つのコレクション=より多くのスペースが必要です
  • 2 db は常に同期されているとは限りません。これにはいくつかの理由があります。
    • クライアントが「AnotherCollection」のデータを手動で変更しました
    • 「AnotherCollection」を追加する前に、「ACollection」にドキュメントがありました。
    • ある時点で変換関数またはソース コレクション スキーマが変更されました

これを修正するには:

AnotherCollection.allow({
    insert: function () {
        return Meteor.isServer;
    },
    update: function () {
        return Meteor.isServer;
    },
    remove: function () {
        return Meteor.isServer;
    }
});

そして、Meteor の起動時に同期します (つまり、コレクションをゼロから構築します)。これは、メンテナンスのため、またはこの新しいコレクションを追加した後に 1 回だけ実行してください。

Meteor.startup(function()
{
    AnotherCollection.remove({});
    var documents = ACollection.find({}).fetch();
    _.each(documents, function(doc)
    {
    var transformedDocument = transformDocument(doc);
    AnotherCollection.insert(transformedDocument);
    });
});
于 2015-06-04T12:49:06.813 に答える