CouchDBの関数を一覧表示する

Habréには、開発者がドキュメントを最後まで読んでいないというコメントがしばしばあります。 CouchDBのリスト関数を発見したとき、私自身がこれに直面しました。



質問はかなり複雑で、ドキュメントではあまり説明されていないように思えたので、評判の良いコミュニティと研究を共有することにしました。



CouchDB設計文書のリスト関数は、単一の関数でデータベース全体を処理できるようにするために必要です。 つまり これは、リレーショナルデータベースの一種のフルテーブルスキャンアナログです。



実際に動作するCouchDBインストールからの設計ドキュメントを検討してください。



{ "_id": "_design/complete", "_rev": "2-45c7b0280b529d99b1d34f362e457860", "views": { "freq": { "map": "function(doc) { emit(doc.REQUEST, 1);}", "reduce": "function (key, values, rereduce){return sum(values);}" } }, "lists": { "basicJSON": "function(head, req) { start({headers :{'Content-Type' : 'text/plain;charset=utf-8'}}); send('{\"head\":'+toJSON(head)+', ');send('\"req\":'+toJSON(req)+', ');send('\"rows\":[');var row;var prev = null;while (row = getRow()){if (prev != null && prev.key == row.key) {} else {if (prev != null) { send(',');} send(toJSON({id: row.id, key: row.key}));} prev = row;} send(']}');}" } }
      
      







CouchDBは、関数の改行を強く嫌うため、すべての関数は1行になります。 読みやすくするために、basicJSON関数をリストにデプロイします。



 function (head, req) { start({ headers: { 'Content-Type': 'text/plain;charset=utf-8' } }); send('{\"head\":' + toJSON(head) + ', '); send('\"req\":' + toJSON(req) + ', '); send('\"rows\":['); var row; var prev = null; while (row = getRow()) { if (prev != null && prev.key == row.key) {} else { if (prev != null) { send(','); } send(toJSON({ id: row.id, key: row.key })); } prev = row; } send(']}');
      
      







ここで面白いのは何ですか?

重要なリンクは処理サイクルです。



  var row; ... while (row = getRow()) { ... send(','); ... send(toJSON({ id: row.id, key: row.key })); ... }
      
      







CouchDBにアクセスするときにHTTPを使用するため、リスト関数はhttp応答を作成します。 つまり 基本的に、何らかのエンコーディングでテキストを生成します。 send()関数がこれを担当します。 サーバーのhttp応答にテキスト文字列を返します。 send(toJSON())コンストラクトを使用できます。 JSONオブジェクトのテキスト表現を返します。



getRow()は、データベース内の次のレコードを取得します。 実際、処理サイクルはそれに基づいて形成されます。



start関数は、http応答のヘッダーを生成します。



上記のリスト関数は次のように呼び出されます。



http:// localhost:5984 / requests-db / _design / complete / _list / basicJSON / freq?reduce = false



データベース名、設計ドキュメント、_list、リスト関数名、プレゼンテーションが表示されます。 次に、プレゼンテーションオプションがあります。 パラメータは、ビューにアクセスするときと同じ方法で指定できます。



したがって、リスト関数を使用すると、必要なデータ処理を実行できます。これは、Map / Reduceを使用しても常に使用できるとは限らないか、クライアントで非常に複雑になります。 ループ内の条件を使用して、レコードの一部をフィルターで除外したり、1つのレコードで複数のsend()呼び出しを行うことができます。これにより、応答のレコード数が増加します。



その結果、機能処理を通過したデータベース内のすべてのレコードを含むhttp-textが構築されます。



はい、もちろん、これは非常に高速な処理ではありませんが、フルテーブルスキャンのリレーショナルデータベースでも、最も遅い処理です。



リスト関数は非常に便利で便利なメカニズムであり、多くの人はドキュメントでは読みません。 少なくとも私。



素敵なコードがあります!



PS。 CouchDBにはまだshow関数がありますが、それについては改めて説明しています。



All Articles