映射/减少 Couchbase 和 Couchbase 之间的差异云蚂蚁
我一直在使用 Couchbase Server,现在只是尝试将本地数据库复制到 Cloudant,但是我的 map/reduce 函数对使用其关联项目构建一组唯一标签时得到了相互冲突的结果...
// map.js
function(doc) {
if (doc.tags) {
for(var t in doc.tags) {
emit(doc.tags[t], doc._id);
}
}
}
// reduce.js
function(key,values,rereduce) {
if (!rereduce) {
var res=[];
for(var v in values) {
res.push(values[v]);
}
return res;
} else {
return values.length;
}
}
在 Cloudbase 服务器中,返回 JSON 如下:
{"rows":[
{"key":"3d","value":["project1","project3","project8","project10"]},
{"key":"agents","value":["project2"]},
{"key":"fabrication","value":["project3","project5"]}
]}
这正是我想要的 &预期的。然而,在 Cloudant 副本上执行相同的查询会返回以下内容:
{"rows":[
{"key":"3d","value":4},
{"key":"agents","value":1},
{"key":"fabrication","value":2}
]}
因此,它以某种方式仅返回值数组的长度... 高度混乱&我很感谢一些 M&R 忍者的见解...;)
I've been playing around with Couchbase Server and now just tried replicating my local db to Cloudant, but am getting conflicting results for my map/reduce function pair to build a set of unique tags with their associated projects...
// map.js
function(doc) {
if (doc.tags) {
for(var t in doc.tags) {
emit(doc.tags[t], doc._id);
}
}
}
// reduce.js
function(key,values,rereduce) {
if (!rereduce) {
var res=[];
for(var v in values) {
res.push(values[v]);
}
return res;
} else {
return values.length;
}
}
In Cloudbase server this returns JSON like:
{"rows":[
{"key":"3d","value":["project1","project3","project8","project10"]},
{"key":"agents","value":["project2"]},
{"key":"fabrication","value":["project3","project5"]}
]}
That's exactly what I wanted & expected. However, the same query on the Cloudant replica, returns this:
{"rows":[
{"key":"3d","value":4},
{"key":"agents","value":1},
{"key":"fabrication","value":2}
]}
So it somehow only returns the length of the value array... Highly confusing & am grateful for any insights by some M&R ninjas... ;)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来这正是您所期望的归约函数的行为。关键部分是这样的:
在Cloudant中,总是调用rereduce(因为reduce需要跨越多个分片)。在这种情况下,rereduce调用values.length,它只会返回数组的长度。
It looks like this is exactly the behavior you would expect given your reduce function. The key part is this:
In Cloudant, rereduce is always called (since the reduce needs to span over multiple shards.) In this case, rereduce calls values.length, which will only return the length of the array.
我更喜欢隐式减少/重新减少,而不是依赖于 rereduce 参数。
然后reduce检查它是否从相同标签累积文档ID,或者是否只是计算不同的标签。
(我没有测试这段代码,但你明白了。只要
tag
值相同,无论是reduce还是rereduce都没关系一旦不同的标签开始一起减少,它就会检测到,因为tag
值会发生变化,所以在那时我就开始积累看来,它也很少值得。
这个技巧,尽管在我 strong>您的具体情况,这是一个危险的减少功能,如果您想查看所有文档,那么您正在构建一个宽列表来查看所有具有标签的文档。有标签,你可以映射它们
现在你可以查询
/db/_design/app/_view/docs_by_tag?key="3d"
你应该得到I prefer to reduce/re-reduce implicitly rather than depending on the
rereduce
parameter.Then reduce checks whether it is accumulating document ids from the identical tag, or whether it is just counting different tags.
(I didn't test this code, but you get the idea. As long as the
tag
value is the same, it doesn't matter whether it's a reduce or rereduce. Once different tags start reducing together, it detects that because thetag
value will change. So at that point just start accumulating.I have used this trick before, although IMO it's rarely worth it.
Also in your specific case, this is a dangerous reduce function. You are building a wide list to see all the docs that have a tag. CouchDB likes tall lists, not fat lists. If you want to see all the docs that have a tag, you could map them.
Now you can query
/db/_design/app/_view/docs_by_tag?key="3d"
and you should get