MongoDB自定义排序

MongoDB自定义排序,mongodb,sorting,Mongodb,Sorting,我收集了如下的记录 { "_id":417, "ptime":ISODate("2013-11-26T11:18:42.961Z"), "p":{ "type":"1", "txt":"test message" }, "users":[ { "uid":"52872ed59542f", "pt":ISODate("2013-11-26T11:18:42.961Z") }, { "uid":"524e

我收集了如下的记录

{
"_id":417,
"ptime":ISODate("2013-11-26T11:18:42.961Z"),
"p":{

    "type":"1",
    "txt":"test message"
},  

"users":[
    {
        "uid":"52872ed59542f",
        "pt":ISODate("2013-11-26T11:18:42.961Z")
    },
    {
        "uid":"524eb460986e4",
        "pt":ISODate("2013-11-26T11:18:42.961Z")
    },
    {
        "uid":"524179060781e",
        "pt":ISODate("2013-11-27T12:48:35Z")
    }
],

},

{
"_id":418,

"ptime":ISODate("2013-11-25T11:18:42.961Z"),
"p":{

    "type":"1",
    "txt":"test message 2"
},  

"users":[
    {
        "uid":"524eb460986e4",
        "pt":ISODate("2013-11-23T11:18:42.961Z")
    },
    {
        "uid":"52872ed59542f",
        "pt":ISODate("2013-11-24T11:18:42.961Z")
    },

    {
        "uid":"524179060781e",
        "pt":ISODate("2013-11-22T12:48:35Z")
    }
],

}

如何按用户uid=“52872ed59542f”的ptime和pt降序对上述记录进行排序?

如果要进行此类排序,可能需要以不同的方式存储数据。MongoDB在处理嵌套文档方面通常不如顶级字段好。在您的情况下,我建议将ptime、pt和uid拆分为各自的集合:

消息

{
    "_id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "type":"1",
    "txt":"test message"
},  
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"52872ed59542f",
    "pt":ISODate("2013-11-26T11:18:42.961Z")
},
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"524eb460986e4",
    "pt":ISODate("2013-11-26T11:18:42.961Z")
},
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"524179060781e",
    "pt":ISODate("2013-11-27T12:48:35Z")
}
用户

{
    "_id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "type":"1",
    "txt":"test message"
},  
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"52872ed59542f",
    "pt":ISODate("2013-11-26T11:18:42.961Z")
},
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"524eb460986e4",
    "pt":ISODate("2013-11-26T11:18:42.961Z")
},
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"524179060781e",
    "pt":ISODate("2013-11-27T12:48:35Z")
}
然后可以在用户集合上为uid、ptime和pt设置索引


不过,您还需要执行两个查询来获取文本消息本身。

如果您想进行此类排序,可能需要以不同的方式存储数据。MongoDB在处理嵌套文档方面通常不如顶级字段好。在您的情况下,我建议将ptime、pt和uid拆分为各自的集合:

db.yourcollection.find(
{
  users:{
     $elemMatch:{uid:"52872ed59542f"}
  }
}).sort({ptime:-1})
消息

{
    "_id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "type":"1",
    "txt":"test message"
},  
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"52872ed59542f",
    "pt":ISODate("2013-11-26T11:18:42.961Z")
},
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"524eb460986e4",
    "pt":ISODate("2013-11-26T11:18:42.961Z")
},
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"524179060781e",
    "pt":ISODate("2013-11-27T12:48:35Z")
}
用户

{
    "_id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "type":"1",
    "txt":"test message"
},  
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"52872ed59542f",
    "pt":ISODate("2013-11-26T11:18:42.961Z")
},
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"524eb460986e4",
    "pt":ISODate("2013-11-26T11:18:42.961Z")
},
{
    "id":417,
    "ptime":ISODate("2013-11-26T11:18:42.961Z"),
    "uid":"524179060781e",
    "pt":ISODate("2013-11-27T12:48:35Z")
}
然后可以在用户集合上为uid、ptime和pt设置索引

不过,您还需要执行两个查询来获取文本消息本身

db.yourcollection.find(
{
  users:{
     $elemMatch:{uid:"52872ed59542f"}
  }
}).sort({ptime:-1})
但您将在“按pt排序”字段中遇到问题。您应该使用聚合框架来投影数据,或者使用Derick的方法


但您将在“按pt排序”字段中遇到问题。您应该使用聚合框架来投影数据或使用Derick的方法。

您可以使用聚合框架先按ptime排序,然后按users.pt字段排序,如下所示

db.users.aggregate(
  {$sort : {'ptime' : 1}},
  {$unwind : "$users"},
  {$match: {"users.uid" : "52872ed59542f"}},
  {$sort : {'users.pt' : 1}},
  {$group : {_id : {id : "$_id", "ptime" : "$ptime", "p" : "$p"}, users : {$push : "$users"}}},
  {$group : {_id : "$_id.id", "ptime" : {$first : "$_id.ptime"}, "p" : {$first : "$_id.p"}, users : {$push : "$users"}}}
);

您可以使用聚合框架先按ptime排序,然后按users.pt字段排序,如下所示

db.users.aggregate(
  {$sort : {'ptime' : 1}},
  {$unwind : "$users"},
  {$match: {"users.uid" : "52872ed59542f"}},
  {$sort : {'users.pt' : 1}},
  {$group : {_id : {id : "$_id", "ptime" : "$ptime", "p" : "$p"}, users : {$push : "$users"}}},
  {$group : {_id : "$_id.id", "ptime" : {$first : "$_id.ptime"}, "p" : {$first : "$_id.p"}, users : {$push : "$users"}}}
);

你不需要这里的$elemMatch,但你需要的是$match!你不需要这里的$elemMatch,但你需要的是$match!