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);
});
});