質問はかなり複雑で、ドキュメントではあまり説明されていないように思えたので、評判の良いコミュニティと研究を共有することにしました。
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関数がありますが、それについては改めて説明しています。