2015-06-12 25 views
0

我想和幾個附加字段的出版物中,但我不希望用Collection.aggregate而失去我的發佈更新,當收集的變化(所以我不能只是在其中使用self.added)。建立與其他字段反應出版物的每個文檔

我打算使用Cursor.observeChanges,以實現這一目標。我有兩個主要的制約因素:

  1. 我不想公佈所有文件字段
  2. 我想用一些未公開的領域創造新的。例如,我有一個字段item其中I存儲item _id的陣列。我不想發佈它,但我要發佈item_count場我場陣列

這裏的長度來的辦法:

  1. 我打算找鏈查詢。我從來沒有這樣做,所以我想知道是否有可能。一般(簡體)查詢結構會是這樣的:http://jsfiddle.net/Billybobbonnet/1cgrqouj/(我不能讓這裏正常顯示的代碼)

  2. 基於the count example in Meteor documentation,我我的查詢存儲在一個變量handle爲了如果客戶停止變化的通知退訂:

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

  3. 我我的查詢前加一個標誌initializing = true;,我只是打電話self.ready();之前設置爲true。我用這個標誌來改變,只有當它是被初始化發佈我itemCount變量。所以基本上,我改變我的switch這樣的:

    switch (field) { case "item" if (!initializing) itemCount = raw_document.item.length; break; default: }

我想檢查,這種做法是犯到我的代碼中大的變化之前和好可能。有人可以證實我是否應該走這條路嗎?

回答

3

即使它們是數據庫查詢的一部分,保留字段也是相對容易的。 self.added的最後一個參數是傳遞給客戶端的對象,因此您可以去除/修改/刪除要發送給客戶端的字段。

這是你的小提琴的修改版本。這應該做你所要求的。(說實話,我不確定你爲什麼在你的小提琴中有observeChanges函數鏈接了任何東西,所以也許我誤解了你,但是看看你的其餘問題就應該是這樣。對不起,如果我弄錯了。 )

var self = this; 

// Modify the document we are sending to the client. 
function filter(doc) { 
    var length = doc.item.length; 

    // White list the fields you want to publish. 
    var docToPublish = _.pick(doc, [ 
     'someOtherField' 
    ]); 

    // Add your custom fields. 
    docToPublish.itemLength = length; 

    return docToPublish;       
} 

var handle = myCollection.find({}, {fields: {item:1, someOtherField:1}}) 
      // Use observe since it gives us the the old and new document when something is changing. 
      // If this becomes a performance issue then consider using observeChanges, 
      // but its usually a lot simpler to use observe in cases like this. 
      .observe({ 
       added: function(doc) { 
        self.added("myCollection", doc._id, filter(doc)); 
       }, 
       changed: function(newDocument, oldDocument) 
        // When the item count is changing, send update to client. 
        if (newDocument.item.length !== oldDocument.item.length) 
         self.changed("myCollection", newDocument._id, filter(newDocument)); 
       }, 
       removed: function(doc) { 
        self.removed("myCollection", doc._id);      
       }); 

self.ready(); 

self.onStop(function() { 
    handle.stop(); 
}); 
+0

先生,我摘下我的帽子。這是一個很好的答案,你的方法就像一個魅力。我有10個自定義字段(不僅是計數),還有16個白名單。你認爲每次觸發'self.changed'都是明智的(性能方面),即使它不會有效地改變客戶端的輸出嗎?還是應該在'self.changed'之前檢查我的10個屬性? – Billybobbonnet

+0

順便說一句,關於'observeChanges',我只是希望它返回同一個擴展了函數的遊標來觀察它。我嘗試了幾個設置,但作爲一個初學者,我覺得這是我的聯盟,想出一個像你這樣的解決方案。 – Billybobbonnet

+0

很好用! 「你認爲每次觸發self.changed都是明智的(性能方面),即使它不會有效地改變客戶端的輸出嗎?」 我認爲一個合理的方法是儘可能保持簡單。如果後來成爲性能問題,那麼您在那個時候處理它。我們在我們的製作流星站點使用了很多,我們還沒有遇到任何重大問題。 順便說一句,如果'item.length'發生變化,這將只會更新文檔。如果你想更新你的其他16個字段,你應該在'changed'回調中刪除'item.length'' if,因此你總是調用'self.changed'。 – datacarl

1

要解決您的第一個問題,您需要告訴MongoDB它應該在遊標中返回哪些字段。離開了你不想要的字段:

MyCollection.find({}, {fields: {'a_field':1}}); 

解決你的第二個問題也是很容易的,我會建議使用collection helpers packages。你可以很容易地做到這一點,就像這樣:對象之前被添加到光標

// Add calculated fields to MyCollection. 
MyCollection.helpers({ 
    item_count: function() { 
    return this.items.length; 
    } 
}); 

這將運行,並會造成對動態計算的,而不是存儲在MongoDB中返回的對象的屬性。

相關問題