急!!!在线等关于mongoose的mapReduce的Nodejs问题
急!!!在线等关于mongoose的mapReduce的Nodejs问题
var o = {};
o.map = function() { emit(this.shopId, this.score); };
o.reduce = function(k, vals) { return { sum: Array.sum(vals), count: vals.length }; };
self.model.mapReduce(o, function(err, items) {
console.log(items);
});
怎么出来的结果跟我预想的不对?
[ { _id: 52b6e1ac3bcdfc6e7fe491d4, value: 3 } ]
预想的不应该是这样的吗:
[ { _id: 52b6e1ac3bcdfc6e7fe491d4, value: { sum: BLAHBLAH, count: BLAHBLAH } } ]
当然可以。让我们一起来分析一下你的代码,并解释为什么你得到的结果与预期不符。
代码分析
首先,让我们看看你提供的代码:
var o = {};
o.map = function() { emit(this.shopId, this.score); };
o.reduce = function(k, vals) { return { sum: Array.sum(vals), count: vals.length }; };
self.model.mapReduce(o, function(err, items) {
console.log(items);
});
问题分析
你希望使用 mapReduce
来计算每个 shopId
的评分总和以及评分数量。然而,你发现输出的结果并不是你期望的形式。
问题原因
问题出在 reduce
函数中。Mongoose 的 mapReduce
方法默认返回的是原始值,而不是你在 reduce
函数中定义的对象。你需要明确告诉 Mongoose 你希望它返回一个对象。
解决方案
你可以通过设置 out
和 finalize
参数来改变输出格式。具体来说,你可以将 out
设置为 { inline: 1 }
来直接在结果中包含 value
字段。
以下是修改后的代码:
var o = {
map: function() { emit(this.shopId, this.score); },
reduce: function(k, vals) {
return { sum: vals.reduce((a, b) => a + b, 0), count: vals.length };
},
out: { inline: 1 },
finalize: function(key, reducedValue) {
return reducedValue;
}
};
self.model.mapReduce(o, function(err, items) {
if (err) {
console.error(err);
} else {
console.log(items);
}
});
代码解释
- Map 函数:这个函数用于发射键值对,其中键是
shopId
,值是score
。 - Reduce 函数:这个函数用于聚合相同
shopId
的所有score
值,并计算总和和计数。 - Out 参数:设置为
{ inline: 1 }
表示直接在结果中包含value
字段。 - Finalize 函数:这个函数用于进一步处理减少后的值,确保它们被正确返回。
预期输出
现在,当你运行这段代码时,你应该会看到类似以下的输出:
[ { _id: 52b6e1ac3bcdfc6e7fe491d4, value: { sum: 10, count: 2 } } ]
这样,你就可以得到你期望的结果了。希望这能解决你的问题!
emit第二个参数的值类型要和reduce的返回一样,比如你这个例子,map里应该类似: emit(this.shopId, {sum: xxx, count: xxx}); 好好研究下官方示例吧。
挖个坟不知道有人帮我讲解一下挖?。。今天我研究map就是做map的然后返回值给reduce的v,然后根据自己需求在reduce里foreach v什么的在设置一个返回值出去。 也就是map做过滤 过滤后的数据给reduce 在做返回
不错 自豪地采用 CNodeJS ionic
喂喂喂,不要挖坟喂,我自己看了羞愧死了 QwQQQQQQQQQQQQ
哈哈…顶上去…让更多人挖…哈哈
From Noder
哦!楼主,我看到了哦!继续搔搔你!
原来你也发过这样的帖子,哈哈
根据你的描述,你的 map
和 reduce
函数看起来是正确的,但返回的结果与预期不符。问题可能在于 Array.sum
方法没有被定义。你需要确保 Array.sum
方法被正确地定义,并且能够在你的环境中使用。
你可以尝试以下代码来实现你的需求:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// 定义一个简单的模型
var shopScoreSchema = new Schema({
shopId: String,
score: Number
});
var ShopScore = mongoose.model('ShopScore', shopScoreSchema);
var o = {
map: function() { emit(this.shopId, this.score); },
reduce: function(k, vals) {
var sum = vals.reduce((acc, val) => acc + val, 0);
return { sum: sum, count: vals.length };
}
};
ShopScore.mapReduce(o, function(err, model) {
if (err) {
console.error(err);
} else {
model.find(function(err, items) {
if (err) {
console.error(err);
} else {
console.log(items);
}
});
}
});
解释
- 定义模型:首先我们定义了一个
shopScoreSchema
模型,包含shopId
和score
字段。 - 定义 map 函数:
map
函数将每个文档的shopId
和score
发射出去。 - 定义 reduce 函数:
reduce
函数计算vals
的总和并统计数量。 - 执行 mapReduce:使用
ShopScore.mapReduce
执行mapReduce
操作,传入map
和reduce
函数。 - 处理结果:在回调函数中处理结果,打印出最终的结果。
如果你发现输出的结果仍然不符合预期,可能需要检查数据是否正确地存储到数据库中,或者检查是否有其他因素影响了结果。