在文档数组的子文档中按字段排序?

时间:2017-03-28 17:49:50

标签: arrays mongodb mongodb-query

我有以下文件:

{
  _id: 1,
  Sc: [
    {
      Ts: ISODate("2017-01-01T10:00:00.000+0000"),
      Sc: 1
    },
    {
      Ts: ISODate("2017-01-02T10:00:00.000+0000"),
      Sc: 2
    },
    {
      Ts: ISODate("2017-01-03T10:00:00.000+0000"),
      Sc: 3
    },
  ]
},
{
  _id: 2,
  Sc: [
    {
      Ts: ISODate("2017-01-01T10:00:00.000+0000"),
      Sc: 100
    },
    {
      Ts: ISODate("2017-01-02T10:00:00.000+0000"),
      Sc: 200
    },
    {
      Ts: ISODate("2017-01-03T10:00:00.000+0000"),
      Sc: 300
    },
  ]
},
{
  _id: 3,
  Sc: [
    {
      Ts: ISODate("2017-01-01T10:00:00.000+0000"),
      Sc: 1
    },
    {
      Ts: ISODate("2017-01-02T10:00:00.000+0000"),
      Sc: 2
    },
    {
      Ts: ISODate("2017-01-03T10:00:00.000+0000"),
      Sc: 3000
    },
  ]
}

我想对Sc数组中的 last 元素(由TS,不一定是物理上最后)的Sc字段进行排序,降序。因此,生成的文档应与上述示例的顺序相反(_id为3,2,1)。

1 个答案:

答案 0 :(得分:1)

您可以将聚合与$unwind一起使用来执行数组解构。 然后你可以选择minTs并按照minTs desc排序。

db.colls.aggregate([
  {$unwind: {path: "$Sc"}}, 
  {$group: {_id: '$_id', minTs: {$min: '$Sc.Ts'}}}, 
  {$sort: {minTs: -1}}
])
{ "_id" : 3, "minTs" : ISODate("2017-01-01T10:00:00Z") }
{ "_id" : 2, "minTs" : ISODate("2017-01-01T10:00:00Z") }
{ "_id" : 1, "minTs" : ISODate("2017-01-01T10:00:00Z") }

使用此解决方案,您将丢失初始Sc阵列,但传输速度会更轻。

如果你想保留它,你可以使用之前的$project将Sc保存在initialSc值中,并在最后的其他$project中使用它:

db.colls.aggregate([{
  $project: {Sc: 1, initialSc: '$Sc'}}, 
  {$unwind: {path: "$Sc"}}, 
  {$group: {_id: { _id: '$_id', Sc: '$initialSc'}, minTs: {$min: '$Sc.Ts'}}}, 
  {$sort: {minTs: -1}}, 
  {$project: {_id: '$_id._id', Sc: '$_id.Sc'}}])
{ "_id" : 3, "Sc" : [
  { "Ts" : ISODate("2017-01-01T10:00:00Z"), "Sc" : 1 }, 
  { "Ts" : ISODate("2017-01-02T10:00:00Z"), "Sc" : 2 }, 
  { "Ts" : ISODate("2017-01-03T10:00:00Z"), "Sc" : 3000 }
] }
{ "_id" : 2, "Sc" : [
  { "Ts" : ISODate("2017-01-01T10:00:00Z"), "Sc" : 100 }, 
  { "Ts" : ISODate("2017-01-02T10:00:00Z"), "Sc" : 200 }, 
  { "Ts" : ISODate("2017-01-03T10:00:00Z"), "Sc" : 300 }
] }
{ "_id" : 1, "Sc" : [ 
  { "Ts" : ISODate("2017-01-01T10:00:00Z"), "Sc" : 1 }, 
  { "Ts" : ISODate("2017-01-02T10:00:00Z"), "Sc" : 2 }, 
  { "Ts" : ISODate("2017-01-03T10:00:00Z"), "Sc" : 3 } 
] }