Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Mongoose/MongoDB:对数组中的元素进行计数_Javascript_Mongodb_Mapreduce_Mongoose - Fatal编程技术网

Javascript Mongoose/MongoDB:对数组中的元素进行计数

Javascript Mongoose/MongoDB:对数组中的元素进行计数,javascript,mongodb,mapreduce,mongoose,Javascript,Mongodb,Mapreduce,Mongoose,我正在尝试使用Mongoose计算集合中数组中字符串的出现次数。我的“模式”如下所示: var ThingSchema = new Schema({ tokens: [ String ] }); 我的目标是获得“Thing”集合中的前10个“token”,每个文档可以包含多个值。例如: var documentOne = { _id: ObjectId('50ff1299a6177ef9160007fa') , tokens: [ 'foo' ] } var document

我正在尝试使用Mongoose计算集合中数组中字符串的出现次数。我的“模式”如下所示:

var ThingSchema = new Schema({
  tokens: [ String ]
});
我的目标是获得“Thing”集合中的前10个“token”,每个文档可以包含多个值。例如:

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' ]
}
…将给我数据结果:

[ foo: 4, bar: 2 baz: 2 ]

我正在考虑为这个工具使用MapReduce和Aggregate,但我不确定什么是最好的选择。

啊哈,我找到了解决方案。MongoDB的
aggregate
框架允许我们在集合上执行一系列任务。特别值得注意的是
$unwind
,它将文档中的一个数组分解为唯一的文档,这样就可以对它们进行分组/计数

在模型上非常容易地公开这一点。使用上面的示例,如下所示:

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 ]
});

在对大约200000条记录进行初步测试时,它明显比MapReduce快,因此可能扩展得更好,但这只是粗略地看一眼。YMMV.

使用
聚合
,除非您希望结果保留在他们自己的集合中。到目前为止,Mongoose的
mapReduce
类已将临时运算符添加到查询中,允许返回结果集而不是持久化。除此之外,还有什么原因让我想改用
aggregate
吗?
aggregate
通常速度更快。聚合框架正是为了处理这样的查询而编写的(over map reduce)。我不能说它的性能有多高,但更高的性能和更低的聚合查询复杂性才是关键。聚合使用C++,而MAP Reduce使用(性能不高)JavaScript