Mongoose / mongodb - 只获得每个身份的最新记录

时间:2015-08-07 06:39:56

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我有一个mongoose的检查模型:

var InspectionSchema = new Schema({
    business_id: {
        type: String,
        required: true
    },
    score: {
        type: Number,
        min: 0,
        max: 100,
        required: true
    },
    date: {
        type: Number, // in format YYYYMMDD
        required: true
    },
    description: String,
    type: String
});

InspectionSchema.index({business_id: 1, date: 1}, {unique: true});

可以对同一个业务进行多次检查(每个业务由唯一的business_id表示)。但是,每个企业每天只能进行一次检查,这就是为什么business_id + date上有唯一索引。

我还在Inspection对象上创建了一个静态方法,给定一个business_id列表,检索底层业务的所有检查。

InspectionSchema.statics.getAllForBusinessIds = function(ids, callback) {
    this.find({'business_id': {$in: ids}}, callback);
};

此功能获取所请求企业的所有检查。但是,我还想创建一个函数,只为每个business_id提取最新的检查。

InspectionSchema.statics.getLatestForBusinessIds = function(ids, callback) {
    // query to get only the latest inspection per business_id in "ids"?
};

我如何实现这个目标?

2 个答案:

答案 0 :(得分:2)

您可以使用.aggregate()方法在一个请求中获取所有最新数据:

Inspection.aggregate(
    [
        { "$sort": { "buiness_id": 1, "date": -1 } },
        { "$group": {
            "_id": "$business_id",
            "score": { "$first": "$score" },
            "date": { "$first": "$date" },
            "description": { "$first": "$description" },
            "type": { "$first": "$type" }
        }}
    ],
    function(err,result) {

    }
);

只需$sort,然后$group,并将“business_id”作为分组键。 $first从分组边界获得第一个结果,我们已经在每个id中按日期排序。

如果您只想要日期,请使用$max

执行此操作
Inspection.aggregate(
    [
        { "$group": {
            "_id": "$business_id",
            "date": { "$max": "$date" }
        }}
    ],
    function(err,result) {

    }
);

如果您希望“预过滤”商家ID值或执行此操作时的任何其他条件,请参阅$match

答案 1 :(得分:0)

试试这个:

Inpection.aggregate(
    [
        { $match : { _id : { "$in" : ids} } },
        { $group: { "_id" : "$business_id", lastInspectionDate: { $last: "$date" } } }
    ],
    function(err,result) {

    }
);