【问题标题】:How to sort inner array and match elements in mongoose如何在猫鼬中对内部数组进行排序和匹配元素
【发布时间】:2015-06-20 17:40:43
【问题描述】:

所以我想在猫鼬中做一个半复杂的查询。如下:

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

基本上,我想做的是找到一个事件,该事件的用户数组中有一个用户,该用户与一个 Id 匹配并且正在参加。我在用户数组中为每个用户有多个用户记录,所以我想找到最近的一个,为此我想按 createTime 对用户数组进行排序。这是错误出现的地方,它只返回undefined。当我不包含排序功能时它工作得很好,有什么方法可以包含它吗?

这是我的 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 }

有没有办法让这个查询完全在猫鼬中?

【问题讨论】:

  • 如果您使用对另一个集合的引用,您可以使用填充函数并对数组中的结果进行排序/限制。但是,看起来你正在使用一个不支持你想要做的事情的子文档。唯一的选择是手动处理每个文档。
  • 看起来您的语法已关闭。尝试正确关闭括号和大括号:Event.findOne({ users: { $elemMatch: { user: someUserId, going: 1 }}}).sort({createTime: -1})

标签: javascript node.js mongodb coffeescript mongoose


【解决方案1】:

作为查找的一部分,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 }
    ]
}

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • OP想要对每个匹配文档中的数组进行排序,而不是匹配文档。
    • 我认为你不能直接这样做,也许使用聚合时可以。
    猜你喜欢
    • 2019-06-19
    • 2014-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多