有一个帐户文档。这个文件有大约1k个席位。对于每个座位,我们会发出一份文件。当然,你会觉得这很慢。 map函数的运行方式如下:
function(doc) {
if (doc.type == 'account') {
doc.seats.map(function(seat) {
emit(seat.userID, doc))
}
}
}
然而,删除doc.seats,然后发出更小的文档似乎没有帮助。
function(doc) {
if (doc.type == 'account') {
doc.seats.map(function(seat) {
delete doc.seats
emit(seat.userID, doc))
}
}
}
有谁理解为什么删除座位不会加速这个?我们可以加快速度的唯一方法是不发出doc对象,只发出一个id。
function(doc) {
if (doc.type == 'account') {
doc.seats.map(function(seat) {
emit(seat.userID, doc.id))
}
}
}
这是在沙发视图中循环播放doc数组的问题吗?
答案 0 :(得分:5)
<强> tldr; 强>
<强>解释强>
以下是您的问题的几点,使用您的示例文档,其中包含一个名为1K条目的席位数组。
在这里发布整个文档是一个坏主意。如果这是一个永久性视图(如果性能完全成问题,您应该始终使用它),您已经获得了一份doc副本,然后制作了1000份副本并通过seat.userID对它们编制索引。这不是有效的。它作为一个临时视图更糟糕,因为它会在每次调用视图时在内存中生成。
AFAIK文档完全不可变,因为通过视图访问,因此您尝试删除席位字段的方式不起作用。因此,删除doc.seats不应该提供任何性能提升,因为您仍然要完成循环并创建1000份原始文档。但是,您可以制作一份没有包含席位的doc的深层副本,并通过emit传递它。
例如:
function(doc) {
var doc_without_seats = JSON.parse(JSON.stringify(doc))
doc_without_seats['seats'] = null;
doc.seats.map( function (seat){
emit(seat.userID, doc_without_seats);
});
}
您确实在发布doc._id而不是doc的正确轨道上。在这种情况下,您构建的索引最大,是大小的1/1000。如果仍需要访问整个文档,则可以在查询时将选项include_docs = true传递给视图。这样就不会将整个文档复制到索引中。
另一个潜在的优化方法是在seat.userID查找内容时发出您想要引用的内容。如果它仍然很大且难以处理,请使用include_docs方法。