如何根据子文档对mongodb查询结果进行排序

如何根据子文档对mongodb查询结果进行排序,mongodb,Mongodb,我在mongodb数据库的分数集合(学生)数据库中有2个文档,如下所示 { id: 2, type: 'newname', subs: [ { time: 20, val: 'b' }, { time: 12, val: 'a' }, { time: 30, val: 'c' } ] }, { id: 1, type: 'strs', subs: [ { time:

我在mongodb数据库的分数集合(学生)数据库中有2个文档,如下所示

{ 
    id: 2, 
    type: 'newname', 
    subs: [
        { time: 20, val: 'b' },
        { time: 12, val: 'a' },
        { time: 30, val: 'c' }
    ] }, { 
    id: 1, 
    type: 'strs', 
    subs: [
        { time: 50, val: 'be' },
        { time: 1, val: 'ab' },
        { time: 20, val: 'cs' }
    ] }
如何构造查询以获得以下结果

{ 
    id: 1, 
    type: 'strs', 
    subs: [
        { time: 1, val: 'ab' },
        { time: 20, val: 'cs' },
        { time: 50, val: 'be' }
    ]
},
{ 
    id: 2, 
    type: 'newname', 
    subs: [
        { time: 12, val: 'a' },
        { time: 20, val: 'b' },
        { time: 30, val: 'c' }
    ]
}
ie:用于根据时间查找文档的查询,必须根据两个条件对结果进行排序

  • 通过idASC
  • 按子文档时间ASC

  • 您可以使用
    cursor.sort(排序)

    例如:

    db.collection.find().sort( { 'id': 1 } )
    
    使用id按升序对结果进行排序

    有关更多详细信息,请参阅以下链接。

    您可以使用
    cursor.sort()
    同时对多个字段(基本上是一个组合)进行排序,但我认为在同时对文档和子文档字段进行排序时,它不起作用。 如果要在顶部文档的两个不同字段上排序,或者在子文档的两个不同字段上排序,那么我想这很好

    因此,您可以使用该框架获得类似的输出。您所要做的就是基本上分解
    subs
    字段的数组,然后再分解它们

    你可以这样做:

    db.col.aggregate({$unwind:'subs'}, {$sort:{id:1,'subs.time':1}});
    
    使用上述代码,您应获得类似以下内容的输出:

     { 
        id: 1, 
        type: 'strs', 
        subs: 
            { time: 1, val: 'ab' }
    },{ 
        id: 1, 
        type: 'strs', 
        subs: 
            { time: 20, val: 'cs' }
    },{ 
        id: 1, 
        type: 'strs', 
        subs: 
            { time: 50, val: 'be' }
    },{ 
        id: 2, 
        type: 'newname', 
        subs: 
            { time: 12, val: 'a' }
    },{ 
        id: 2, 
        type: 'newname', 
        subs: 
            { time: 20, val: 'b' }
    },{ 
        id: 2, 
        type: 'newname', 
        subs: 
            { time: 30, val: 'c' }
    }
    

    奇怪的是,MongoDB没有提供任何通过查询对子文档进行排序的方法。似乎您必须更新子文档的自然排序顺序,如下所示:

    如果这些是您的收藏中仅有的两份文档,请在下面的查询中填写:

    db.test.update( {}, {$push : {"subs" :{$each  : [] , $sort : {time : -1}}}})
    
    然后运行查询对ID本身进行排序:

    db.test.find().sort({'id':1}).pretty()
    
    您将得到低于输出的值

    {                                                             
    
            "id" : 1,                                             
            "type" : "strs",                                      
            "subs" : [                                            
                    {                                             
                            "time" : 50,                          
                            "val" : "be"                          
                    },                                            
                    {                                             
                            "time" : 20,                          
                            "val" : "cs"                          
                    },                                            
                    {                                             
                            "time" : 1,                           
                            "val" : "ab"                          
                    }                                             
            ]                                                     
    }                                                             
    {                                                             
    
            "id" : 2,                                             
            "type" : "newname",                                   
            "subs" : [                                            
                    {                                             
                            "time" : 30,                          
                            "val" : "c"                           
                    },                                            
                    {                                             
                            "time" : 20,                          
                            "val" : "b"                           
                    },                                            
                    {                                             
                            "time" : 12,                          
                            "val" : "a"                           
                    }                                             
            ]                                                     
    }     
    
    希望它能解决你的问题。以下为参考资料:


    当按顺序使用时,
    $unwind
    $sort
    $group
    阵列专用

    • 解构数组
      subs
    • subs.time
      以升序(1)排列
    • 通过
      id
      ,并使用
      $push
      重新构造
      subs
      数组,对象和其他字段仍然使用
      $first
    • 隐藏
      \u id
    • $sort
      id
      升序排序

    如何对包含列表项的子文档进行排序,我需要根据列表中的内键时间对列表进行排序。这就是我所需要的。我认为排序子文档是不可能的。预期的解决方案是{id:1,类型:'strs',subs:[{time:1,val:ab'},{time:20,val:cs'},{time:50,val:be'},{id:2,类型:'newname',subs:[{time:12,val:a'},{time:20,val'b'},{time:30,val'c'}]}正确,我已经有一段时间没有看到这一点了,但您可以将分组作为我编写的聚合的最后一步,并使用$addToSet获得所需的输出。如果您愿意,我可以编写查询…@tzik请编写完整的查询以获得预期的解决方案。我需要这样做same@tzik你可以回答这个问题:[我也需要这样做,你能分享你的解决方案吗?
    db.collection.aggregate([
      { $unwind: "$subs" },
    
      { $sort: { "subs.time": 1 } },
    
      {
        $group: {
          _id: "$id",
          id: { $first: "$id" },
          type: { $first: "$type" },
          subs: { $push: "$subs" }
        }
      },
    
      { $project: { _id: 0 } },
    
      { $sort: { id: 1 } }
    ])