查询最新唯一对象的集合

时间:2015-04-27 19:39:57

标签: mongodb mongoose

问题:让我们说集合中有以下对象:

我如何按"product_id"返回一条记录,而只返回"version"个最高的记录?这是否可以在猫鼬中做到?

{
    "_id" : ObjectId("54f765564b10883c1800002a"),
    "total_invoice_fob_case" : 86.70999999999999,
    "status" : "Draft",
    "discount" : "3.40",
    "effective_date" : ISODate("2013-08-01T06:00:00.000Z"),
    "version" : 2,
    "controlstate" : "AB",
    "controlstate_id" : ObjectId("54d510e9e3d793f581b6bb27"),
    "product" : "Product A",
    "product_id" : ObjectId("54f75b5e4b1088801a000627"),
    "size" : "1.75LTR",
    "size_id" : ObjectId("5418a3dd750b4294c2cb3a47"),
    "vendor" : "BEAM SUNTORY",
    "vendor_id" : ObjectId("54ef5aa74b1088781b000169"),
    "product_state_code" : "123",
    "net_fob_cost" : 86.70999999999999,
    "change_reason" : [ 
        "Other"
    ],
    "submitted" : {
        "submitted_date" : ISODate("2014-05-16T06:00:00.000Z")
    }
},
{
    "_id" : ObjectId("54f765564b10883c1800002b"),
    "total_invoice_fob_case" : 86.70999999999999,
    "status" : "Draft",
    "discount" : "4.40",
    "effective_date" : ISODate("2013-08-01T06:00:00.000Z"),
    "version" : 3,
    "controlstate" : "AB",
    "controlstate_id" : ObjectId("54d510e9e3d793f581b6bb27"),
    "product" : "Product A",
    "product_id" : ObjectId("54f75b5e4b1088801a000627"),
    "size" : "1.75LTR",
    "size_id" : ObjectId("5418a3dd750b4294c2cb3a47"),
    "vendor" : "BEAM SUNTORY",
    "vendor_id" : ObjectId("54ef5aa74b1088781b000169"),
    "product_state_code" : "123",
    "net_fob_cost" : 86.70999999999999,
    "change_reason" : [ 
        "Other"
    ],
    "submitted" : {
        "submitted_date" : ISODate("2014-05-16T06:00:00.000Z")
    }
},
{
    "_id" : ObjectId("54f765564b10883c1800002c"),
    "total_invoice_fob_case" : 86.70999999999999,
    "status" : "Draft",
    "discount" : "3.40",
    "effective_date" : ISODate("2013-08-01T06:00:00.000Z"),
    "version" : 2,
    "controlstate" : "AB",
    "controlstate_id" : ObjectId("54d510e9e3d793f581b6bb27"),
    "product" : "Product B",
    "product_id" : ObjectId("54f75b5e4b1088801a000628"),
    "size" : "1.75LTR",
    "size_id" : ObjectId("5418a3dd750b4294c2cb3a47"),
    "vendor" : "BEAM SUNTORY",
    "vendor_id" : ObjectId("54ef5aa74b1088781b000169"),
    "product_state_code" : "123",
    "net_fob_cost" : 86.70999999999999,
    "change_reason" : [ 
        "Other"
    ],
    "submitted" : {
        "submitted_date" : ISODate("2014-05-16T06:00:00.000Z")
    }
}

2 个答案:

答案 0 :(得分:2)

对于Mongo的aggregation framework来说,这听起来像是一份工作。您可以从this example推断如何解决问题。

更新:要使用最高版本按product_id检索一个,您还需要使用$first

db.products.aggregate([
  {$sort: {product_id: 1, version: -1}}, // sort first so that $first pulls the correct record
  {$group: {
    _id: {product_id: '$product_id'}, // group by the product_id
    product: {$first: $$ROOT} // only return the first document per group
  }}
]);

答案 1 :(得分:1)

您需要 aggregation pipeline ,首先使用$sort管道阶段按版本号降序对集合中的文档进行排序,然后按{{1}对已排序的文档进行分组使用$group运算符。在分组中,使用 product_id 上的$first运算符返回已排序组中的第一个文档:

$$ROOT

控制台输出

var pipeline = [
    {
        "$sort": { "version": -1 }
    },
    {
        "$group": {
            "_id": "$product_id",
            "value": {
                "$first": "$$ROOT"
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "product_id": "$_id",
            "status": "$value.status",
            "version": "$value.version",
            "product" : "$value.product"
        }    
    }
 ];

// Mongoose aggregation
Model.aggregate(pipeline, function (err, res) {
  if (err) return handleError(err);
  console.log(res); // 
});

- 更新 -

要投影完整文档,请使用以下内容替换$project管道:

[ 
    {
        "product_id" : ObjectId("54f75b5e4b1088801a000628"),
        "status" : "Draft",
        "version" : 2,
        "product" : "Product B"
    }, 
    {
        "product_id" : ObjectId("54f75b5e4b1088801a000627"),
        "status" : "Draft",
        "version" : 3,
        "product" : "Product A"
    }
]

<强>输出

{
    "$project": {
        "_id": 0,
        "product": "$value"
    }
}