使用 mongodb Aggregate 对嵌套对象进行排序?

Posted

技术标签:

【中文标题】使用 mongodb Aggregate 对嵌套对象进行排序?【英文标题】:Sort in nasted Object using mongo db Aggregate? 【发布时间】:2021-02-26 05:34:35 【问题描述】:

我有故事数据,我想通过基于 createdDate 的 desc 内部对象对其进行排序。 y代码在下面

Story.aggregate(
[
   
    "$project" :  
        "_id" : 0, 
        "stories" : "$$ROOT"
    
, 
 
    "$lookup" :  
        "localField" : "stories.user", 
        "from" : "users", 
        "foreignField" : "_id", 
        "as" : "users"
    
, 
 
    "$unwind" :  
        "path" : "$users", 
        "preserveNullAndEmptyArrays" : false
    
, 
 
    "$lookup" :  
        "localField" : "stories.place", 
        "from" : "places", 
        "foreignField" : "_id", 
        "as" : "places"
    
, 
 
    "$unwind" :  
        "path" : "$places", 
        "preserveNullAndEmptyArrays" : true
    
,
 
    "$lookup" :  
        "localField" : "places.categories", 
        "from" : "categories", 
        "foreignField" : "_id", 
        "as" : "categories"
    
, 
 
    "$unwind" :  
        "path" : "$categories", 
        "preserveNullAndEmptyArrays" : false
    
, 
     $match:  "stories._id": mongoose.Types.ObjectId(req.params.id) ,
    
     "$sort":"stories.comments.createdDate":-1
    ,
     
        "$project" :  
            "stories._id" : "$stories._id", 
            "stories.title" : "$stories.title",
            "stories.createdDate" : "$stories.createdDate", 
            "stories.image" : "$stories.image", 
            "stories.likeCount" : "$stories.likeCount", 
            "stories.commentCount" : "$stories.commentCount", 
            "stories.likes" : "$stories.likes", 
            "stories.comments" : "$stories.comments",              
            "stories.story" : "$stories.story", 
            "users.firstName" : "$users.firstName",
            "users.storiesCount" : "$users.storiesCount", 
            "users.albumsCount" : "$users.albumsCount",
            "stories.urlTitle" : "$stories.urlTitle",
            "users._id" : "$users._id",
            "users.lastName" : "$users.lastName", 
            "users.image" : "$users.image", 
            "places.placeName" : "$places.placeName", 
            "places._id" : "$places._id", 
            "categories.categoryName" : "$categories.categoryName",
            "categories._id" : "$categories._id",                  
        
      
    ]
     

在这段代码中,我想根据 cmets.created 日期对评论进行排序。我从 db 收到的数据是

 
    "stories": 
        "_id": "5f86b6b4d11dfd67b083ce9c",
        "title": "Information about Khunjrab Pass.",
        "createdDate": "2020-10-14T09:31:00.407Z",
        "image": "Khunjerab-Pass.jpg",
        "likeCount": 0,
        "commentCount": 0,
        "likes": [
            "5f93d8571240934378d5ba06",
            "5f65ed4552e1d9156af84bd8"
        ],
        "comments": [
            
                "_id": "5faf7e858de22b3a94bbc5a5",
                "userId": "5f93d8571240934378d5ba06",
                "comment": "some comment",                    
                "createdDate": "2020-11-14T06:51:49.269Z",
                "updatedDate": "2020-11-14T06:51:49.269Z",
                "likes": [
                    "5f9a53138dca473d58ae6e39"
                ],
            ,
            
                "_id": "5faf9a136525194c0077eddc",
                "userId": "5f65c4b7a9267211bfa994ff",
                "comment": "some comment",
               
                "likes": [
                    "5f9a53138dca473d58ae6e39"
                ],
            ,
            
                "_id": "5fafa5996525194c0077eddd",
                "userId": "5f65c4b7a9267211bfa994ff",
                "comment": "when we visited khunjrab top there was strong wind and very low temperature.",
                "firstName": "Sohaib",
                "lastName": "Siddique",
                "createdDate": "2020-11-14T09:38:33.789Z",
                "updatedDate": "2020-11-14T09:38:33.789Z",
                "likes": [
                    "5f9a53138dca473d58ae6e39"
                ],
                "image": "sohaib-img.jpeg"
            
        ],
        "story": "Khunjerab Pass is a high mountain pass in the Karakoram Mountains, in a strategic position on the northern border of Pakistan and on the southwest border of China. Its elevation is 4,693 metres",
        "urlTitle": "prince-saiful-malook-and-badri-jamala"
    ,
    "users": 
        "firstName": "Sohaib",
        "storiesCount": 1,
        "albumsCount": 0,
        "_id": "5f65c4b7a9267211bfa994ff",
        "lastName": "Siddique",
        "image": "sohaib-img.jpeg"
    ,
    "places": 
        "placeName": "Khunjerab Pass",
        "_id": "5f65e66752e1d9156af84bd4"
    ,
    "categories": 
        "categoryName": "Passes",
        "_id": "5f65cf7452e1d9156af84bcb"
    

在这个故事中,我有两个关于故事的 cmets 我想根据 cmets.createdDate 对评论进行排序,但我没有得到任何解决方案的期望结果?

提前致谢

【问题讨论】:

如果您使用的是 MongoDB4.4 版本,那么您可以使用 $function 运算符,第二个选项您需要 $unwind cmets 数组,然后使用排序阶段,然后 $group 您的 cmets。 【参考方案1】:

根据您的文档,您可以应用以下聚合:

db.collection.aggregate([
  
    "$unwind": "$stories.comments"
  ,
  
    "$sort": 
      "stories.comments.createdDate": -1
    
  ,
  
    "$group": 
      "_id": "_id",
      "comments": 
        "$push": "$stories.comments"
      ,
      "stories": 
        "$first": "$stories"
      ,
      "users": 
        "$first": "$users"
      ,
      "places": 
        "$first": "$places"
      ,
      "categories": 
        "$first": "$categories"
      
    
  ,
  
    "$set": 
      "stories.comments": "$comments"
    
  ,
  
    "$project": 
      "comments": 0
    
  
])

【讨论】:

以上是关于使用 mongodb Aggregate 对嵌套对象进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose/Mongodb Aggregate - 对多个字段进行分组和平均

Mongodb中数据聚合之聚合管道aggregate

mongodb aggregate

MongoDB聚合(aggregate)常用操作及示例

MongoDB:使用嵌套的 $group 聚合

MongoDB聚合(aggregate)