“合并"在 CouchDB 中查看归类为有用的输出 [英] "merge" view collation into useful output in CouchDB

查看:14
本文介绍了“合并"在 CouchDB 中查看归类为有用的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 CouchDB 中进行加入" 时,您可以使用视图排序规则将记录分组在一起.例如,有两种文档类型 customersorders.这样您就可以返回客户,然后是该客户的所有订单,然后是下一个客户和订单.

When doing a "join" in CouchDB, you can use view collation to group the records together. For example, having two document types customers and orders. So that you can return customer, then all the orders for that customer, then the next customer, and orders.

问题是,您如何合并行,以便如果您有 10 个客户和 40 个订单,您的输出仍然是 10 行而不是 50 行.您基本上将更多信息添加到您的 customer 行.

The question is, how do you do a merging of rows, so that if you have 10 customers, and 40 orders, your output is still 10 rows instead of 50. You essentially add more information into your customer row.

我相信使用 _listreduce 可以解决这个问题.问题是具体如何做到这一点?

I believe using a _list or a reduce will solve this. The question is how exactly to do this?

推荐答案

我第二个jhs answer,但我认为他的选项2"太危险了.我很难学会.您可以将 reduce 函数用于许多不错的事情,例如 获取博客每个用户的最后一篇文章,但您不能将其用于不减少返回数据量的任何事情.

I second jhs answer, but I think his "Option 2" is too dangerous. I learned it the hard way. You can use reduce function for many nice things like getting the last post of each user of a blog, but you cannot use it for anything which does not reduce the amount of data returned.

为了用事实支持它,我制作了这个小脚本来生成 200 个客户,每个客户有 20 个订单.

To support it with facts, I made this little script to generate 200 customers with 20 orders each.

#!/bin/bash
echo '{"docs":['
for i in $(seq 1 200); do
  id=customer/$i
  echo '{"_id":"'$id'","type":"customer","name":"Customer '$i'"},'
  for o in $(seq 1 20); do
    echo '{"type":"order","_id":"order/'$i'/'$o'", "for":"'$id'", "desc":"Desc '$i$o'"},'
  done
done
echo ']}'

这是很可能发生的情况,只需抛出 Error: reduce_overflow_error.

It is a very likely scenario and it is enough to throw a Error: reduce_overflow_error.

恕我直言,您有两个选择:

IMHO the two option you have are:

方案一:优化列表功能

通过一点点工作,您可以手动构建 JSON 响应,这样您就不需要在数组中累积订单.

With a little bit of work, you can build the JSON response by hand, so that you do not need to accumulate orders in an array.

我已经编辑了 jhs 的列表函数以避免使用任何数组,因此您可以拥有任意数量的客户.

I have edited the list function of jhs to avoid any use of arrays, so you can have customers with any number of orders.

function(head, req) {
  start({'headers':{'Content-Type':'application/json'}});

  var first_customer = true
    , first_order = true
    , row
    ;

  send('{"rows":[');

  while(row = getRow()) {
    if(row.key[1] === 2) {
      // Order for customer
      if (first_order) {
        first_order = false;
      } else {
        send(',');
      }
      send(JSON.stringify(row.value));
    }
    else if (row.key[1] === 1) {
      // New customer
      if (first_customer) {
        first_customer = false;
      } else {
        send(']},');
      }
      send('{"customer":');
      send(JSON.stringify(row.key[0]));
      send(',"orders":[');
      first_order = true;
    }
  }
  if (!first_customer)
    send(']}');

  send('
]}');
}

选项 2:针对您的用例优化文档

如果你真的需要将订单放在同一个文档中,那么问问你自己是否可以这样存储,避免在查询时进行任何处理.

If you really need to have the orders in the same document, then ask yourself if you can store it this way and avoid any processing while querying.

换句话说:尝试充分利用文档数据库提供的可能性.设计文档以最适合您的用例,并减少使用它们所需的后处理.

In other words: try to fully exploit the possibilities offered by a document database. Design the documents to best fit your use case, and reduce the post-processing needed to use them.

这篇关于“合并"在 CouchDB 中查看归类为有用的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆