簡體   English   中英

couchdb更新設計文檔

[英]couchdb update design doc

我有一個nodejs應用程序,我使用nano使用以下腳本連接到我的couchdb:

const { connectionString } = require('../config');

const nano = require('nano')(connectionString);

// creates database or fails silent if exists
nano.db.create('foo');

module.exports = {
  foo: nano.db.use('foo')
}

此腳本在每個服務器啟動時運行,因此每次服務器(重新)啟動時它都會嘗試創建數據庫'foo',如果數據庫已經存在則只是靜默失敗。

我非常喜歡這個想法,因為這樣我實際上在應用程序級別維護數據庫,並且在我決定添加新數據庫時不必手動創建數據庫。

采取這種方法更進一步,我還嘗試從應用程序級別維護我的設計文檔。

... 
nano.db.create('foo');

const foo = nano.db.use('foo');

const design = {
  _id: "_design/foo",
  views: {
    by_name: {
      map: function(doc) {
        emit(doc.name, null);
      }
    }
  }
}

foo.insert(design, (err) => {
  if(err)
    console.log('design insert failed');
})

module.exports = {
  foo
}

顯然,如果設計文檔不存在,它只會插入設計文檔。 但是,如果我更新了我的設計文檔並希望更新它會怎么樣?

我試過了:

foo.get("_design/foo", (err, doc) => {
  if(err)
    return foo.insert(design);

  design._rev = doc._rev
  foo.insert(design);
})

現在的問題是每次服務器重新啟動都會更新設計文檔(例如,每次重新啟動時都會獲得一個新的_rev)。

現在......我的問題:)

1:這對於使用數據庫和設計引導我的CouchDB是一種糟糕的方法嗎? 我應該考慮將一些遷移步驟作為部署過程的一部分嗎?

2:我的設計文檔有多少 _revs,基本上是每次部署和服務器重啟都是一個問題嗎? 即使文件本身沒有改變? 如果是這樣,有沒有辦法只更新文件? (我想在我的應用程序中手動將_rev設置為某個值,但非常不確定這是個好主意)。

  1. 你的方法似乎很合理。 如果檢查僅在重新啟動時發生,則這甚至不是性能問題。
  2. 太多的_rev 可能會成為一個問題。 _revs的歷史記錄保存為_revs_info並與文檔本身一起存儲(有關詳細信息,請參閱CouchDB文檔) 根據您的設置,創建不必要的修訂可能是一個錯誤的決定。

我們遇到了一些需要某些視圖的服務器端腳本的類似挑戰。 我們的解決方案是計算舊設計文檔和新設計文檔的哈希值並進行比較。 您可以對此作業使用任何散列函數,例如sha1md5 只需記住在散列它之前從舊文檔中刪除_rev,否則每次都會得到不同的哈希值。

我嘗試了像@Bernhard Gschwantner建議的md5比較。 但是我遇到了一些困難因為我的情況我想在我的代碼中用純javascript在設計文檔中編寫map / reduce函數。

const design = {
  _id: "_design/foo",
  views: {
    by_name: {
      map: function(doc) {
        emit(doc.name, null);
      }
    }
  }
}

從CouchDb獲取設計文檔時,返回轉換為字符串的map / reduce函數:

  ...
  "by_name": {
    "map": "function (doc) {\n        emit(doc.name, null);\n      }"
  },
  ...

顯然md5比較在這里確實不起作用。

我在設計文檔上添加了一個版本號,最終得到了一個非常簡單的解決方案:

const design = {
  _id: "_design/foo",
  version: 1,
  views: {
    by_name: {
      map: function(doc) {
        emit(doc.name, null);
      }
    }
  }
}

當我更新設計文檔時,我只是增加版本號並將其與數據庫中的版本號進行比較:

const fooDesign = {...}
foo.get('_design/foo', (err, design) => {
  if(err)
    return foo.insert(fooDesign);

  console.log('comparing foo design version', design.version, fooDesign.version);
  if(design.version !== fooDisign.version) {
    fooDesign._rev = design._rev;
    foo.insert(fooDesign, (err) => {
      if(err)
        return console.log('error updating foo design', err);
      console.log('foo design updated to version', fooDesign.version)
    });
  }
});

再次回顧你的問題:在最近的一個項目中,我使用了Johannes Schmidt的偉大的couchdb-push模塊。 您可以免費獲得條件更新,以及從其依賴項couchdb-compile繼承的許多 其他 好處

這個圖書館對我來說是一個隱藏的寶石。 強烈推薦!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM