2

nano次のスクリプトを使用して、couchdb に接続する nodejs アプリケーションがあります。

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: 基本的にすべての展開とサーバーの再起動のたびに、設計ドキュメントが多くの_rev を取得することは問題ですか? ドキュメント自体は変わっていないのに?もしそうなら、ドキュメントが変更された場合にのみドキュメントを更新する方法はありますか? (アプリケーションで_revを手動で値に設定することを考えましたが、それが良いアイデアかどうかは非常にわかりません)。

4

3 に答える 3

2

@Bernhard Gschwantnerが提案したように、md5の比較を試みました。しかし、私の場合、設計ドキュメントの map/reduce 関数を純粋な JavaScript でコードに記述したいので、いくつかの問題に遭遇しました。

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)
    });
  }
});
于 2016-07-16T12:26:11.377 に答える