4

我有这样的文件:

{
   "_id": ObjectId("4d17c7963ffcf60c1100002f"),
   "title": "Text",
   "params": {
     "brand": "BMW",
     "model": "i3"
    }
}

{
   "_id": ObjectId("4d17c7963ffcf60c1100002f"),
   "title": "Text",
   "params": {
     "brand": "BMW",
     "model": "i5"
    }
}

我需要的是每个参数值的计数。像:

brand
---------
BMW (2)

model
---------
i3 (1)
i5 (1)

我想我必须编写 map/reduce 函数。我怎样才能做到这一点?谢谢。

4

2 回答 2

2

我想我必须编写 map/reduce 函数。

是的,你需要一个 map-reduce。有关一些简单的 map-reduce 示例,请查看此处

对于您的特定情况,您首先需要更改对输出的期望。map/reduce 的输出是一个集合。该集合看起来(在您的情况下)如下所示:

{ key : { 'brand' : 'bmw' }, value : 2 }
{ key : { 'model' : 'i5' }, value : 1 }

要生成这个集合,您需要一个“map”函数和一个“reduce”函数。“map”函数将发出一个键和一个值。键是 params 的每个元素,值是 1 的计数。“reduce”函数接受一个键和一个值数组,只返回一个值。您的问题与MongoDB 站点上的此示例基本相同:

map = function() {
    if (!this.params) {
        return;
    }
    for (index in this.params) {
        emit(this.params[index], 1);
    }
}

reduce = function(previous, current) {
    var count = 0;

    for (index in current) {
        count += current[index];
    }

    return count;
}
于 2010-12-27T07:21:46.743 回答
1

在您的 map 函数中枚举对象的 params 属性的属性this。对于您找到的每个属性emit,使用包含属性名称和属性值的键调用。传递 1 作为值。例如emit({'brand','BMW'}, 1) ,但显然使用变量而不是常量!

在您的 reduce 函数中,您将获得一个键和一个值数组。对这些值求和并返回总和。即使初始数组全为 1,也不要试图使用数组的长度,因为可以迭代地调用 reduce 函数。

您可以随后从结果集合中对结果进行分组,并在必要时应用索引以提高性能。

于 2010-12-27T06:47:05.023 回答