我应该如何为Mongoose的每个相关文档计算文档?

时间:2015-06-24 03:11:20

标签: node.js mongodb mongoose

我有一个标签列表,对于每个标签,我想计算该标签的文档(作业)总数。

这适用于一些标签和一些文档,但现在我有超过100个标签和200个文档,因此查询以总结每个标签的所有文档需要10-15秒。

    data = pandas.read_csv(turnstile_weather)
    data = data[['Hour','ENTRIESn_hourly']]
    data['normalized_entries'] = data['Hour']
    data_by_hour = data.groupby(['Hour'])
    data_by_totalh = data_by_h.sum()
    data_by_totalh = data_by_totalh.reset_index()
    m= data_by_totalh.sort(columns='ENTRIESn_hourly')
    m['normalized_entries']=m['ENTRIESn_hourly']/m['ENTRIESn_hourly'].sum()
   # plot = ggplot(data_by_totalh,aes('Hour','ENTRIESn_hourly')) + geom_histogram(position='stack',stat='identity')
    m2 = m[['normalized_entries','Hour']]
    for i in range(1,len(data['Hour'])):
        data['normalized_entries'][i] = m2['normalized_entries'][data['Hour'][i]]

这是我能想到的最好的但是查询所有标签的速度非常慢,而且每个标签都按标签查询所有文件。

编辑:这是工作架构...

/**
 * Get tags
 */
exports.list = function (req, res) {
    Tag.find()
        .execQ()
        .then(function (tags) {
            utils.tag.getJobCountByTags(tags, user)
                .then(function(tagsWithCount){
                    res.json(tagsWithCount);
                });
        })
        .fail(function(err){
            res.send(err);
        });
};


//utils.tag namespace
tag.getJobCountByTags = function (tags, user){
    var queries = tags.map(function(tag){
        return getJobCountByTag(tag, user);
    });

    return q.all(queries);
};

function getJobCountByTag(tag, user){
    var Job = mongoose.model('Job');
    var whereData = {};
    var tagId = tag._id;

    if ( tag.type === 'skillTag' ) {
        whereData.skillTags = tagId;
    } else if ( tag.type === 'roleTag' ) {
        whereData.roleTags = tagId;
    }

    return Job
        .find(whereData)
        .execQ()
        .then(function (jobs) {
            tag._doc.count = jobs.length;

            return tag;
        });

}

1 个答案:

答案 0 :(得分:0)

您可以尝试使用聚合框架来获得所需的结果。以下聚合管道具有第一阶段作为 $uwnind 运算符,用于从输入文档解构数组字段以输出每个元素的文档。每个输出文档都是输入文档,其中数组字段的值由元素替换。然后,您可以使用 $group 运算符按照标记类型标识符表达式对前一个 $uwnind 管道中的输入文档进行分组,并应用累加器表达式{ {3}}到每个小组获取计数:

function getJobCountByTag(tag){
    var Job  = mongoose.model('Job', jobSchema);,
        tagType = "$"+tag.type+"s",
        pipeline = [
            { "$unwind": tagType },
            {
                "$group": {
                    "_id": tagType,
                    "count": { "$sum": 1 }
                 }
            }
        ];

    return Job
        .aggregate(pipeline)
        .execQ()
        .then(function (res) {
            tag._doc.count = res.count;

            return tag;
        });
}

或使用聚合管道构建器Fluent API

function getJobCountByTag(tag){
    var Job = mongoose.model('Job'),
        tagType = "$"+tag.type+"s",

    return Job
        .aggregate()
        .unwind(tag.type+"s")
        .group({
            "_id": tagType,
            "count": { "$sum": 1 }
        })
        .execQ()
        .then(function (res) {
            tag._doc.count = res.count;

            return tag;
        });
}