14

顧客注文の2つのドキュメントタイプがあるとします。顧客ドキュメントには名前、住所などの基本情報が含まれ、注文は顧客が何かを注文するたびにすべての注文情報が含まれます。ドキュメントを保存する場合、タイプ=注文またはタイプ=顧客。

10人の顧客と30件の注文のセットに対してマップ関数を実行すると、40行が出力されます。一部の行は顧客になり、一部は注文になります。

問題は、注文情報が顧客情報を含む行の中に「詰め込まれる」ように、reduceをどのように書くかです。したがって、10行(10人の顧客)が返されますが、各顧客に関連するすべての注文が返されます。

基本的に、出力に個別のレコードは必要ありません。それらを結合して(注文を1つの顧客行に)、reduceが方法だと思いますか?

4

1 に答える 1

30

これはビュー照合と呼ばれ、CouchDB の非常に便利な手法です。

reduce幸いなことに、一歩も必要ありません。map顧客とその注文を「ひとまとめ」にするために使用します。

設定

重要なのは、顧客ごとに一意の ID が必要であり、顧客ドキュメントと注文ドキュメントの両方で識別できる必要があるということです。

顧客例:

{ "_id": "customer me@example.com"
, "type": "customer"
, "name": "Jason"
}

注文例:

{ "_id": "abcdef123456"
, "type": "order"
, "for_customer": "customer me@example.com"
}

お客様 ID をドキュメントとして便利に使用しました_idが、重要なことは、両方のドキュメントがお客様の ID を知っていることです。

精算

目標はマップ クエリです。指定する?key="customer me@example.com"と、(1) 最初に顧客情報が返され、(2) すべての注文が返されます。

このマップ関数はそれを行います:

function(doc) {
  var CUSTOMER_VAL = 1;
  var ORDER_VAL    = 2;
  var key;

  if(doc.type === "customer") {
    key = [doc._id, CUSTOMER_VAL];
    emit(key, doc);
  }

  if(doc.type === "order") {
    key = [doc.for_customer, ORDER_VAL];
    emit(key, doc);
  }
}

すべての行は、主にドキュメントの顧客に基づいて並べ替えられ、「タイブレーカー」並べ替えは整数 1 または 2 のいずれかになります。これにより、顧客ドキュメントは常に対応する注文ドキュメントの上に並べ替えられます。

["customer me@example.com", 1], ...customer doc...
["customer me@example.com", 2], ...customer's order...
["customer me@example.com", 2], ...customer's other order.
... etc...
["customer another@customer.com", 1], ... different customer...
["customer another@customer.com", 2], ... different customer's order

PS あなたがすべてに従う場合: 代わりに1、顧客にとって2より良い価値があるかもしれませんnull, 次に、注文の注文タイムスタンプ. 以前と同じように並べ替えられますが、注文の時系列リストが表示されるようになりました。

于 2011-05-20T00:55:12.203 に答える