【问题标题】:Mongoose/mongodb - get only latest records per idMongoose/mongodb - 仅获取每个 id 的最新记录
【发布时间】:2015-10-30 12:20:55
【问题描述】:

我在猫鼬中有一个检查模型:

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

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

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

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"?
};

我该如何实现这个?

【问题讨论】:

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


    【解决方案1】:

    您可以使用.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

    【讨论】:

    • 这非常有效。解释也很好。感谢您的帮助!
    【解决方案2】:

    试试这个:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      • 2020-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 2021-12-14
      相关资源
      最近更新 更多