Eri*_*ale 7 javascript mapreduce mongoose mongodb
我正在尝试使用Mongoose计算我的集合中数组中字符串的出现次数.我的"架构"看起来像这样:
var ThingSchema = new Schema({
tokens: [ String ]
});
Run Code Online (Sandbox Code Playgroud)
我的目标是在"Thing"集合中获得前10个"标记",每个文档可以包含多个值.例如:
var documentOne = {
_id: ObjectId('50ff1299a6177ef9160007fa')
, tokens: [ 'foo' ]
}
var documentTwo = {
_id: ObjectId('50ff1299a6177ef9160007fb')
, tokens: [ 'foo', 'bar' ]
}
var documentThree = {
_id: ObjectId('50ff1299a6177ef9160007fc')
, tokens: [ 'foo', 'bar', 'baz' ]
}
var documentFour = {
_id: ObjectId('50ff1299a6177ef9160007fd')
, tokens: [ 'foo', 'baz' ]
}
Run Code Online (Sandbox Code Playgroud)
...会给我数据结果:
[ foo: 4, bar: 2 baz: 2 ]
Run Code Online (Sandbox Code Playgroud)
我正在考虑将MapReduce和Aggregate用于此工具,但我不确定什么是最佳选择.
Eri*_*ale 22
啊哈,我找到了解决方案.MongoDB的aggregate框架允许我们在集合上执行一系列任务.尤其值得注意的是$unwind,它打破文档到阵列中的唯一文件,使他们能够组/计数集体.
MongooseJS在模型上非常容易地暴露这种情况.使用上面的示例,如下所示:
Thing.aggregate([
{ $match: { /* Query can go here, if you want to filter results. */ } }
, { $project: { tokens: 1 } } /* select the tokens field as something we want to "send" to the next command in the chain */
, { $unwind: '$tokens' } /* this converts arrays into unique documents for counting */
, { $group: { /* execute 'grouping' */
_id: { token: '$tokens' } /* using the 'token' value as the _id */
, count: { $sum: 1 } /* create a sum value */
}
}
], function(err, topTopics) {
console.log(topTopics);
// [ foo: 4, bar: 2 baz: 2 ]
});
Run Code Online (Sandbox Code Playgroud)
在大约200,000条记录的初步测试中,它明显快于MapReduce,因此可能会更好地扩展,但这只是在粗略浏览之后.因人而异.