2014-02-08 59 views
1

我正在使用JSON-RPC抓取一個90K記錄數據庫,並試圖進行一些基本的錯誤檢查。我想先用兩個不同的設置抓取數據庫兩次,然後在第二個刮片上添加一個前綴。這樣我可以檢查以確保這兩個設置不會產生不同的記錄(由於丟失的更新等)。我想用一個視圖來實現比較,該視圖將來自第一個刮片的每個文檔與由第二個刮片產生的兩個文檔進行比較,然後用它們之間的差異發出記錄的名稱。在CouchDB視圖中引用外部文檔

但是,我無法完全弄清楚如何在視圖中插入另一個文檔,我所閱讀的所有內容僅使用emit()函數討論外部文檔,這太遲了,無法對其進行比較。在下面的例子中,lookup()函數將抓取引用的文檔。

這難道不可能嗎?

function(doc) { 
    if(doc._id.slice(0,1)!=='$' && doc._id.slice(0,1)!== "_"){ 
    var otherDoc = lookup('$test" + doc._id); 
    if(otherDoc){ 
    var keys = doc.value.keys(); 
    var same = true; 
    keys.forEach(function(key) { 
     if ((key.slice(0,1) !== '_') && (key.slice(0,1) !=='$') && (key!=='expires')) { 
     if (!Object.equal(otherDoc[key], doc[key])) { 
      same = false; 
     } 
     } 
    }); 
     if(!same){ 
     emit(doc._id, 1); 
     } 
    } 
    } 
} 

回答

2

語境

你是正確的,這是不可能在CouchDB中。 map函數的全部要點是它必須是冪等的,否則你會失去預先計算好的索引的所有其他好處。

這就是爲什麼你不能訪問map函數中的外部資源,無論它們是其他記錄還是時鐘。任何時候你運行一張地圖,如果你把相同的記錄放進去,你總是得到相同的結果。由於CouchDB中的記錄之間沒有關係,因此您不能保證這是可能的。

解決方案

但是,你仍然可以實現你的最終目標,只是不同的手段。一些可能性...

  • 假設有在每個文檔一些有意義的數值,你可以使用一個視圖採取所有這些值({key: <batch id>, value: <meaningful number>})之和組他們通過導入你沒有。然後比較客戶端或瀏覽器中的兩個數字,看看它們是否匹配。

  • 蠻力的方法是使用視圖來配對應該匹配的文檔。每個文檔位於不同的行上,但它們按照公共字段分組。然後遍歷整個索引比較對。這肯定是最快的代碼,並且不依賴於您的應用程序或數據。

  • 實施驗證功能以強制執行數據模式。只需要警告,這會降低寫入吞吐量,因爲每個寫入的記錄都將從Erlang輸入到JS引擎中。此外,只有在您擔心形成正確的記錄而不是確切的內容時才適用,但情況可能並非如此。

  • 而不是你創建不同文檔的不同批處理作業,讓他們把它們放到同一個文檔。結構可能如下所示:{ "_id": "something meaningful", "batch_one": { ..data.. }, "batch_two": { ..data.. } }然後,您的驗證功能可以比較它們,或者您可以創建一個視圖,將所有不匹配的文檔編入索引。所有這些都取決於您想要執行錯誤檢查和更正的管道中的哪個位置。

個人而言,我喜歡最後的選擇更好的,但只有當你不打算使用的數據庫是在生產。 IE瀏覽器。,你不想在每條記錄中攜帶所有額外的數據。

希望有所幫助。

乾杯。