Using map reduce in CouchDB to output fewer rows

后端 未结 1 1893
野趣味
野趣味 2020-12-13 16:06

Lets say you have two document types, customers and orders. A customer document contains basic information like name, address etc. and orders<

相关标签:
1条回答
  • 2020-12-13 16:35

    This is called view collation and it is a very useful CouchDB technique.

    Fortunately, you don't even need a reduce step. Just use map to get the customers and their orders "clumped" together.

    Setup

    The key is that you need a unique id for each customer, and it has to be known both from customer docs and from order docs.

    Example customer:

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

    Example order:

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

    I have conveniently used the customer ID as the document _id but the important thing is that both docs know the customer's identity.

    Payoff

    The goal is a map query, where if you specify ?key="customer me@example.com" then you will get back (1) first, the customer info, and (2) any and all orders placed.

    This map function would do that:

    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);
      }
    }
    

    All rows will sort primarily on the customer the document is about, and the "tiebreaker" sort is either the integer 1 or 2. That makes customer docs always sort above their corresponding order docs.

    ["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
    

    P.S. If you follow all that: instead of 1 and 2 a better value might be null for the customer, then the order timestamp for the order. They will sort identically as before except now you have a chronological list of orders.

    0 讨论(0)
提交回复
热议问题