在MongoDB中,如何根据嵌入对象中的属性对文档进行排序?

时间:2013-02-14 14:03:01

标签: mongodb sorting

在我的产品系列中,我可以找到所有已在“GB”区域发布的产品:

> db.products.find({'release.region':'GB'}).pretty();

{
        "_id" : "foo",
        "release" : [
                {
                        "region" : "GB",
                        "date" : ISODate("2012-03-01T00:00:00Z")
                },
                {
                        "region" : "US",
                        "date" : ISODate("2012-09-01T00:00:00Z")
                }
        ]
}
{
        "_id" : "bar",
        "release" : [
                {
                        "region" : "FR",
                        "date" : ISODate("2010-07-01T00:00:00Z")
                },
                {
                        "region" : "GB",
                        "date" : ISODate("2012-05-01T00:00:00Z")
                }
        ]
}
{
        "_id" : "baz",
        "release" : [
                {
                        "region" : "GB",
                        "date" : ISODate("2011-05-01T00:00:00Z")
                },
                {
                        "region" : "NZ",
                        "date" : ISODate("2012-02-01T00:00:00Z")
                }
        ]
}

如何使用GB发布日期按升序日期顺序对结果进行排序? (例如,订单应该是baz,foo,bar)

注意,我无法在客户端进行排序。

或者,我怎样才能更好地组织数据以实现这一目标。

编辑:我更改了“bar”的FR发布日期,以说明vivek的解决方案不正确。

1 个答案:

答案 0 :(得分:2)

因为除了“GB”区域之外,您不需要release个元素,所以可以使用aggregate这样做:

db.products.aggregate(
    // Filter the docs to just those containing the 'GB' region
    { $match: {'release.region': 'GB'}},
    // Duplicate the docs, one per release element
    { $unwind: '$release'},
    // Filter the resulting docs to just include the ones from the 'GB' region
    { $match: {'release.region': 'GB'}},
    // Sort by release date
    { $sort: {'release.date': 1}})

输出:

{
  "result": [
    {
      "_id": "baz",
      "release": {
        "region": "GB",
        "date": ISODate("20110501T00:00:00Z")
      }
    },
    {
      "_id": "foo",
      "release": {
        "region": "GB",
        "date": ISODate("20120301T00:00:00Z")
      }
    },
    {
      "_id": "bar",
      "release": {
        "region": "GB",
        "date": ISODate("20120501T00:00:00Z")
      }
    }
  ],
  "ok": 1
}