简体   繁体   English

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

[英]How To Sort mongodb query results based on subdocuments

i am having 2 documents in score collections(student)databases like below in mongodb database.我在 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' }
    ] }

How to construct a query to get the below result如何构造查询以获得以下结果

{ 
    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: a query for find the documents based on time and have to sort the results on 2 criteria即:根据时间查找文档的查询,并且必须根据 2 个条件对结果进行排序

  1. by id ASCID ASC
  2. by sub document time ASC按子文档时间ASC

You can use cursor.sort() to sort on multiple fields (basically a combo) at the same time but I don't think it works when sorting on both a document and a subdocument field at the same time.您可以使用cursor.sort()同时对多个字段(基本上是一个组合cursor.sort()进行排序,但我认为它在同时对文档和子文档字段进行排序时不起作用。 If you were to sort on two different fields of the top document or on two different fields of a subdocument then it would be fine i guess.如果您要对顶部文档的两个不同字段或子文档的两个不同字段进行排序,那么我猜就可以了。

So you can get a similar output using the aggregation framework.因此,您可以使用聚合框架获得类似的输出。 All you have to do is basically break down the arrays of the subs field and then sort them.您所要做的基本上就是分解subs字段的数组,然后它们进行排序

You could do something like:你可以这样做:

db.col.aggregate({$unwind:'subs'}, {$sort:{id:1,'subs.time':1}});

With the above code you should get an output similar to this:使用上面的代码,您应该得到类似于以下内容的输出:

 { 
    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' }
}

Strangely, MongoDB does not provide any method to sort sub documents by querying it.奇怪的是,MongoDB 并没有提供任何通过查询对子文档进行排序的方法。 It seems you will have to update the natural sort order of the sub docs as shown below :看来您必须更新子文档的自然排序顺序,如下所示:

If these are the only 2 docs in your collection, write below query :如果这些是您收藏中仅有的 2 个文档,请写下查询:

db.test.update( {}, {$push : {"subs" :{$each  : [] , $sort : {time : -1}}}})

and then run query to sort on ID itself :然后运行查询以对 ID 本身进行排序:

db.test.find().sort({'id':1}).pretty()

You will get below output.您将获得以下输出。

{                                                             

        "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"                           
                }                                             
        ]                                                     
}     

Hope it solves you situation.希望它能解决你的情况。 Below is the reference :以下是参考:

http://docs.mongodb.org/manual/reference/operator/update/sort/#sort-array-of-documents-by-a-field-in-the-documents http://docs.mongodb.org/manual/reference/operator/update/sort/#sort-array-of-documents-by-a-field-in-the-documents

It is possible when use in sequence $unwind > $sort > $group specialty for array,可以按顺序使用$unwind > $sort > $group special for array,

db.collection.aggregate([
  { $unwind: "$subs" },
  • $sort subs.time in ascending (1) order $sort subs.time升序(1)
  { $sort: { "subs.time": 1 } },
  • $group by id , and re-construct subs array using $push objects and other fields remain using $first $group by id ,并使用$push对象重新构建subs数组,其他字段仍然使用$first
  {
    $group: {
      _id: "$id",
      id: { $first: "$id" },
      type: { $first: "$type" },
      subs: { $push: "$subs" }
    }
  },
  { $project: { _id: 0 } },
  • $sort by id in ascending order $sortid升序
  { $sort: { id: 1 } }
])

Playground游乐场

You can use cursor.sort(sort)您可以使用cursor.sort(sort)

For Exapmle:例如:

db.collection.find().sort( { 'id': 1 } )

to sort the results using id in ascending order.使用 id 按升序对结果进行排序。

For more details refer the following link.有关更多详细信息,请参阅以下链接。http://docs.mongodb.org/manual/reference/method/cursor.sort/http://docs.mongodb.org/manual/reference/method/cursor.sort/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM