Node.js 检查相同的数据是否按预期工作

Node.js 检查相同的数据是否按预期工作,node.js,mongoose,Node.js,Mongoose,我有一个大型MongoDB数据库,因为尝试计数文档使其下降,我需要为此创建一个函数: 查询是: M_logs[from] .find() .select('referer') .where('time') .gt(lower_bound) .lt(upper_bound); 这给了我减少,真实的数据是>1k的文档: [ { _id: 53db8f924a1cb7d34a0001e3, referer: '' }, { _id: 5

我有一个大型MongoDB数据库,因为尝试计数文档使其下降,我需要为此创建一个函数:

查询是:

M_logs[from]
      .find()
      .select('referer')
      .where('time')
      .gt(lower_bound)
      .lt(upper_bound);
这给了我减少,真实的数据是>1k的文档:

[ { _id: 53db8f924a1cb7d34a0001e3, referer: '' },
  { _id: 53dbe3ef4a1cb7655b008f4d, referer: '' },
  { _id: 53dbe3ef4a1cb7655b008f4e, referer: '' },
  { _id: 53dbe3ef4a1cb7655b008f4f,
    referer: 'http://www.url1.com'
  { _id: 53dbe3ef4a1cb7655b008f50,
    referer: 'http://url1.com' },
  { _id: 53dbe3ef4a1cb7655b008f51,
    referer: 'http://www.url1.com' }
  { _id: 53dbe3ef4a1cb7655b008f52,
    referer: 'http://www.url1.com' },
  { _id: 53dbe3ef4a1cb7655b008f53,
    referer: 'http://www.url1.com'
  { _id: 53ed5bc64a1cb7f78c00361e,
    referer: 'http://url1.com' },
  { _id: 53ef80384a1cb7019c0000c5,
    referer: 'http://url2'}
]
如您所见,有些日志有缺陷且为空,有些日志的url前缀为www,有些日志则不是。因为我需要显示每个url提供给我们的访问者数量,所以我需要对它们进行解析,以仅获取“url1.com”、“url2.com”,并忽略空字段。并计算每次出现的次数

代码是:

function referer_process(result, referer, index, j, callback) {

    var ur,
        host;

    result.forEach(function (element) {
        ur = url.parse(element.referer, false, false);

        if (ur.host) {
            if (ur.host.search('www.') === 0) {
                host = ur.host.substring(4);
            } else {
                host = ur.host;
            }
            if (!index[host]) {
                console.log('.' + host + '. ' + host.length);
                index[host] = j;
                j = j + 1;
                referer[index[host]] = {name: host, y: 1};
            } else {
                referer[index[host]].y = referer[index[host]].y + 1;
            }
        }
    });

    callback(referer, index, j);

}
当我们看到结果时,问题就出现了,如果解析后结果的前两行具有相同的referer,则其中一行被分配给不同的计数,但其他一切都正常

例如:

url1.com: 5
url1.com: 1
url2.com: 1
我不明白这是怎么发生的,forEach是同步的,所以索引一定是在第二次遇到url1时创建的


这怎么会发生?在哪里可以搜索解决方案?

我建议您在mongo shell中使用mapReduce来解决此类问题。以下是您如何使用它:

TIME_UPPER_BOUND = ...
TIME_LOWER_BOUND = ...

var map = function() {
    var host = this.referer;
    if (host && host.substring(0, 4) == 'http') {
        host = host.substring(7);
    }
    if (host && host.substring(0, 3) == 'www') {
        host = host.substring(4);
    }
    emit(host, 1);
};

var reduce = function(key, values) {
    return Array.sum(values);
};

var option = {
    query: {time: {$gt: TIME_LOWER_BOUND, $lt: TIME_UPPER_BOUND}},  
    out: {inline: 1},
};

db.refers.mapReduce(map, reduce, option).results;
根据您上面提供的数据,这将输出:

[
    {
        "_id" : "",
        "value" : 3
    },
    {
        "_id" : "url1.com",
        "value" : 6
    },
    {
        "_id" : "url2",
        "value" : 1
    }
]

很干净。记住用上面的集合名称替换引用:db..mapReduce。您可以在此处找到有关mapReduce的更多信息:

我不得不对其进行了大量调整,以将其纳入我的自定义框架中。我使用了query-ervrywhere-where-where-but-there,但这确实非常有效: