我有一个bug,当在视图函数中发出键后改变键时,会导致错误的视图结果。当在发射上做key.slice()
时,错误消失了,但是视图函数变得非常慢。我想避免做任何不必要的克隆。你知道在发出密钥后是否有可能改变它们吗?(这些变化只影响局部状态,而不影响文档)。
'map' : "function(doc) {
key = [doc.foo];
emit(key, null);
key[0] = doc.bar;
emit(key, null);
}
当它工作时(在发出键时进行克隆):
'map' : "function(doc) {
key = [doc.foo];
emit(key.slice(), null);
key[0] = doc.bar;
emit(key.slice(), null);
}
我找不到关于emit实际做什么的任何文档-它是在内存中存储对对象的引用还是克隆或序列化传递给它的对象?前者可以在一定程度上解释我注意到的行为,而后者意味着我现在正在进行不必要的克隆,并且我的代码存在其他问题。所以我的问题是:你知道emit是如何实现的以及它是如何影响代码的吗?
什么发出
Emit返回一组关键字数据(在您的示例中为null),以及获取该数据的文档的详细信息。
假设您的文档显示了一组时间内一组地点的天气数据,那么您可能希望以以下格式返回键:
emit([ location, measure, year, month, day, hour ], relevant_data)
您可以将relevant_data
设置为null
,并在查询中使用include_docs=true
选项以获取文档作为响应的一部分。但是,这是一种不好的做法,并且可能导致在检索视图之后更新文档的竞争条件。
另一种选择是返回实际相关的数据。因此,如果你在一个地方有多个天气观测,你可能想要在每次观测中发射它们。
你错在哪里
如果map函数导致异常,则不返回任何内容。我认为slice
函数需要一个您打算返回的元素的参数。这将触发一个异常并且不返回任何数据。
如果要在数组中每个元素返回一个键,则必须遍历键中元素的长度,并对每个元素进行emit操作。