优化MongoDB聚合查询

时间:2018-01-23 16:48:27

标签: mongodb aggregation-framework

我是Mongo的新手,我能够创建一个提供我需要的输出的查询。但它出来的时间很长(看似简单的查询)。

欢迎提供有关如何优化它的提示。

总结一下,我有5个项目,查询应该获得该项目的最后修改项目上次修改项目的信息+ 名称项目的其他项目。它还需要检索所有其他项目的名称和ID

这是一个项目的样本(所有类似的东西):

{
"_id" : ObjectId("5a16ebc6871fbc64c0e39e43"),
"date_modified" : ISODate("2017-12-15T07:18:04.774Z"),
"name" : "TEST COMPANY 1",
"projects" : [ 
    {
        "project" : {
            "name" : "TEST PROJECT 1",
            "date_modified" : ISODate("2014-12-15T07:18:04.774Z"),
            "description" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quam velit, vulputate eu pharetra nec, mattis ac neque. Duis vulputate commodo lectus, ac blandit elit tincidunt id. Sed rhoncus, tortor sed eleifend tristique, tortor mauris molestie elit, et lacinia ipsum quam nec dui. Quisque nec mauris sit amet elit iaculis pretium sit amet quis magna. Aenean velit odio, elementum in tempus ut, vehicula eu diam. Pellentesque rhoncus aliquam mattis. Ut vulputate eros sed felis sodales nec vulputate justo hendrerit. Vivamus varius pretium ligula, a aliquam odio euismod sit amet. Quisque laoreet sem sit amet orci ullamcorper at ultricies metus viverra. Pellentesque arcu mauris, malesuada quis ornare accumsan, blandit sed diam.",
            "url" : "test_project_1",
            "task_groups" : [ 
                {
                    "task_group" : {
                        "id" : "1",
                        "folders" : [ 
                            {
                                "folder" : {
                                    "name" : "test folder 1",
                                    "tasks" : [ 
                                        {
                                            "task" : {
                                                "name" : "test task 1",
                                                "versions" : [ 
                                                    {
                                                        "version" : {
                                                            "id" : "1"
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    ]
                                }
                            }
                        ],
                        "tasks" : [ 
                            {
                                "task" : {
                                    "name" : "test task 1",
                                    "versions" : [ 
                                        {
                                            "version" : {
                                                "id" : "1"
                                            }
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }, 
    {
        "project" : {
            "name" : "TEST PROJECT 2",
            "date_modified" : ISODate("2017-12-15T07:18:04.774Z"),
            "description" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quam velit, vulputate eu pharetra nec, mattis ac neque. Duis vulputate commodo lectus, ac blandit elit tincidunt id. Sed rhoncus, tortor sed eleifend tristique, tortor mauris molestie elit, et lacinia ipsum quam nec dui. Quisque nec mauris sit amet elit iaculis pretium sit amet quis magna. Aenean velit odio, elementum in tempus ut, vehicula eu diam. Pellentesque rhoncus aliquam mattis. Ut vulputate eros sed felis sodales nec vulputate justo hendrerit. Vivamus varius pretium ligula, a aliquam odio euismod sit amet. Quisque laoreet sem sit amet orci ullamcorper at ultricies metus viverra. Pellentesque arcu mauris, malesuada quis ornare accumsan, blandit sed diam.",
            "url" : "test_project_1",
            "task_groups" : [ 
                {
                    "task_group" : {
                        "id" : "1",
                        "folders" : [ 
                            {
                                "folder" : {
                                    "name" : "test folder 1",
                                    "tasks" : [ 
                                        {
                                            "task" : {
                                                "name" : "test task 1",
                                                "versions" : [ 
                                                    {
                                                        "version" : {
                                                            "id" : "1"
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    ]
                                }
                            }
                        ],
                        "tasks" : [ 
                            {
                                "task" : {
                                    "name" : "test task 1",
                                    "versions" : [ 
                                        {
                                            "version" : {
                                                "id" : "1"
                                            }
                                        }
                                    ]
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
]

}

这是我的查询,就像我说的,它完成了工作,但我不确定我使用Mongo聚合的选项有多好:

const searchQuery = collection.aggregate([
    {
        "$sort": {
            "date_modified": -1,
        }
    },
    {
        "$group": {
            "_id": 0,
            "firstPipe": { "$first": { "name": "$name", "id": "$_id", "date_modified": "$date_modified", "projects": "$projects" } },
            "otherCompanies": { "$push": { "name": "$name", "id": "$_id" } },
        }
    },
    { $unwind: "$firstPipe.projects" },
    {
        "$sort": {
            "firstPipe.projects.project.date_modified": -1
        }
    },
    {
        "$group": {
            "_id": 0,
            "firstProject": { "$first": "$firstPipe.projects" },
            "projectNames": { "$push": { "project": { "name": "$firstPipe.projects.project.name" } } },
            "secondPipe": { "$first": { "name": "$firstPipe.name", "id": "$firstPipe.id", "date_modified": "$firstPipe.date_modified" } },
            "otherCompanies": { "$first": "$otherCompanies" }
        }
    },
    {
        "$project": {
            "projects": { "$concatArrays": [["$firstProject"], { "$slice": ["$projectNames", 1, { "$size": "$projectNames" }] }] },
            "secondPipe": "$secondPipe",
            "otherCompanies": "$otherCompanies"
        }
    },
    {
        "$group": {
            "_id": 0,
            "thirdPipe": { "$push": { "name": "$secondPipe.name", "id": "$secondPipe.id", "date_modified": "$secondPipe.date_modified", "projects": "$projects" } },
            "otherCompanies": { "$first": "$otherCompanies" }
        }
    },
    {
        "$project": {
            "data": { "$concatArrays": ["$thirdPipe", { "$slice": ["$otherCompanies", 2, { "$size": "$otherCompanies" }] }] }
        }
    },
    { "$unwind": "$data" },
    { "$replaceRoot": { "newRoot": "$data" } },
]);

这是我得到并要求的输出:

[
  {
    "name": "TEST COMPANY 1",
    "id": "5a16ebc6871fbc64c0e39e43",
    "date_modified": "2017-12-15T07:18:04.774Z",
    "projects": [
      {
        "project": {
          "name": "TEST PROJECT 2",
          "date_modified": "2017-12-15T07:18:04.774Z",
          "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quam velit, vulputate eu pharetra nec, mattis ac neque. Duis vulputate commodo lectus, ac blandit elit tincidunt id. Sed rhoncus, tortor sed eleifend tristique, tortor mauris molestie elit, et lacinia ipsum quam nec dui. Quisque nec mauris sit amet elit iaculis pretium sit amet quis magna. Aenean velit odio, elementum in tempus ut, vehicula eu diam. Pellentesque rhoncus aliquam mattis. Ut vulputate eros sed felis sodales nec vulputate justo hendrerit. Vivamus varius pretium ligula, a aliquam odio euismod sit amet. Quisque laoreet sem sit amet orci ullamcorper at ultricies metus viverra. Pellentesque arcu mauris, malesuada quis ornare accumsan, blandit sed diam.",
          "url": "test_project_1",
          "task_groups": [
            {
              "task_group": {
                "id": "1",
                "folders": [
                  {
                    "folder": {
                      "name": "test folder 1",
                      "tasks": [
                        {
                          "task": {
                            "name": "test task 1",
                            "versions": [
                              {
                                "version": {
                                  "id": "1"
                                }
                              }
                            ]
                          }
                        }
                      ]
                    }
                  }
                ],
                "tasks": [
                  {
                    "task": {
                      "name": "test task 1",
                      "versions": [
                        {
                          "version": {
                            "id": "1"
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            }
          ]
        }
      },
      {
        "project": {
          "name": "TEST PROJECT 1"
        }
      }
    ]
  },
  {
    "name": "TEST COMPANY 4",
    "id": "5a16ebc6871f1c64c0e39e41"
  },
  {
    "name": "TEST COMPANY 3",
    "id": "5a16ebc6871fbc64c0e39e11"
  },
  {
    "name": "TEST COMPANY 2",
    "id": "5a16ebc6871fbc64c0e39e41"
  }
]

1 个答案:

答案 0 :(得分:1)

您可以通过移动逻辑来分离项目来简化一点。

一些变化

$group现在负责通过在$max中找到$cond修改日期$map来分割项目,以便在修改的最大日期与修改后的最新日期匹配时返回整个项目文档project element else返回名称。

$addFields阶段将项目嵌入主文档中。

[
  {"$sort":{"date_modified":-1}},
  {"$group":{
    "_id":0,
    "topdata":{"$first":{"name":"$name","id":"$_id","date_modified":"$date_modified"}},
    "projects":{
      "$first":{
        "$let":{
          "vars":{"ldm":{"$max":"$projects.project.date_modified"}},
          "in":{
            "$map":{
              "input":"$projects",
              "as":"project",
              "in":{
                "$cond":{
                  "if":{"$eq":["$$project.project.date_modified","$$ldm"]},
                  "then":"$$project",
                  "else":{"project":{"name":"$$project.project.name"}}
                }
              }
            }
          }
        }
      }
    },
    "otherCompanies":{"$push":{"name":"$name","id":"$_id"}}
  }},
  {"$unwind":"$projects"},
  {"$sort":{"projects.project.date_modified":-1}},
  {"$group":{
    "_id":0,
    "topdata":{"$first":"$topdata"},
    "projects":{"$push":"$projects"},
    "otherCompanies":{"$first":"$otherCompanies"}
  }},
  {"$addFields":{"topdata.projects":"$projects"}},
  {"$project":{"data":{"$concatArrays":[["$topdata"],{"$slice":["$otherCompanies",1,{"$size":"$otherCompanies"}]}]}}},
  {"$unwind":"$data"},
  {"$replaceRoot":{"newRoot":"$data"}}
]