面试题答案
一键面试实现思路
- 设计视图:在CouchDB的设计文档中创建视图。视图的映射函数需要从订单文档中提取下单时间(精确到月)和商品种类作为键,以订单总价作为值。
- reduce函数:使用reduce函数对每个键(即每个月每种商品)对应的值(总价)进行求和,从而得到每个月每种商品的销售总额。
- 性能优化:
- 预计算:定期进行视图重建,在数据量变化较大时提前计算好统计结果,减少实时查询的压力。
- 索引:确保设计文档中的视图已正确索引,CouchDB会根据视图的映射函数自动创建索引,可通过
_compact
操作优化索引。 - 分区:如果数据量极大,可以考虑基于时间或商品类别等进行数据库分区,减少单个视图处理的数据量。
代码实现
- 创建设计文档和视图:
假设我们有一个名为
orders
的数据库。首先,我们需要创建一个设计文档,例如命名为stats
。- 映射函数:
function (doc) {
if (doc.type === 'order') {
var month = doc.order_time.getFullYear() + '-' + (doc.order_time.getMonth() + 1);
emit([month, doc.product_type], doc.total_price);
}
}
这段映射函数从订单文档中提取下单时间的年月和商品种类作为键,订单总价作为值。doc.type === 'order'
假设文档中有一个字段type
标识这是订单文档,你可能需要根据实际情况调整。
- reduce函数:
function (keys, values, rereduce) {
return sum(values);
}
这个简单的reduce函数对每个键对应的所有总价进行求和。sum
是CouchDB内置的用于求和的函数。
- 查询视图: 使用HTTP请求查询视图:
GET /orders/_design/stats/_view/monthly_product_sales
CouchDB会返回每个月每种商品的销售总额数据。例如返回的数据格式可能类似:
{
"total_rows": 10,
"offset": 0,
"rows": [
{
"key": ["2023-10", "product1"],
"value": 1000
},
{
"key": ["2023-10", "product2"],
"value": 1500
}
]
}
其中key
的第一个元素是年月,第二个元素是商品种类,value
是该月该商品的销售总额。