如何在mongoose中对内部数组和匹配元素进行排序

时间:2015-04-14 22:53:42

标签: javascript node.js mongodb coffeescript mongoose

所以我试图在mongoose中进行半复杂的查询。它如下:

Event.findOne({ users: { $elemMatch: { user: someUserId, going: 1 }, sort: {createTime: -1} } }

基本上我想要做的是找到一个单独的事件,其用户数组中的用户与Id匹配并且正在参加。我有用户数组中每个用户的多个用户记录,所以我想找到最新的用户记录,为此我想用createTime对用户数组进行排序。这是错误发生的地方,它只返回undefined。当我没有包含sort函数时,它的工作正常,有没有办法包含它?

这是我的Event对象的样子:

{ 
  _id: 1,
  endTime: 1429060173865,
  createTime: 1429051773902,
  startTime: 1429052973865,
  description: 'some desc',
  creator: 2,
  users:
   [ { user: 1,
       status: 1,
       going: 1,
       createTime: 1429051773749,
       _id: 552d997d8e923847306e2c21 },
     { user: 1,
       status: 1,
       going: 1,
       createTime: 1429051773922,
       _id: 552d997d8e923847306e2c25 },
     { user: 1,
       status: 9,
       going: 0,
       createTime: 1429051773942,
       _id: 552d997d8e923847306e2c26 } ],
  destroyed: 0 }

有没有办法完全用mongoose进行查询?

2 个答案:

答案 0 :(得分:3)

作为find的一部分,MongoDB无法对文档的数组字段进行排序。您可以定义Mongoose虚拟以按排序顺序返回数组。您还可以按排序顺序维护数组,如下所示:

> db.test.drop()
// note: not in order when inserted
> db.test.insert({ "_id" : 0, "users" : [
    { "user" : 1, "going" : 1, "created" : 22 },
    { "user" : 2, "going" : 1, "created" : 775 },
    { "user" : 1, "going" : 1, "created" : 6432 }
] })
// insert user to array and sort as part of update
> db.test.update({ "_id" : 0 },
    { "$push" : { 
        "users" : {
            "$each" : [{ "user" : 2, "going" : 1, "created" : 5532 }],
            "$sort" : { "created" : -1 }
        }
    } })
> > db.test.findOne()
{
    "_id" : 0,
    "users" : [
        { "user" : 1, "going" : 1, "created" : 6432 },
        { "user" : 2, "going" : 1, "created" : 5532 },
        { "user" : 2, "going" : 1, "created" : 775 },
        { "user" : 1, "going" : 1, "created" : 22 }
    ]
}

这样,当您执行查找查询时,匹配文档中的数组将已按所需顺序排列。

答案 1 :(得分:0)

您的查询未正确写入。为了排序,你应该在find的第三个参数中写出来:

Event.findOne(
     { users: 
           { $elemMatch: { user: someUserId, going: 1 }}
     },
     null,
     { 
         sort: {createTime: -1} 
     },
     function(err, event) {
         //your event here
     });