在mongodb中仅将嵌套对象投影为动态字段名称

问题描述 投票:1回答:1

我有一个名为logins的mongodb集合。结构如下,

{
  id: 1,
  name: "N1",
  tasks: {
    project1: {
      task7: {
        count: 10
        time: 1.2
      },
      task3: {
        count: 56
        time: 1050
      }
    },
    project25: {
      task7: {
        count: 25
        time: 10
      }
    }
  }
}

我想获取显示的“ task7”的详细信息,而与“项目”级别无关。如下所示,有可能吗?

db.logins.find({tasks.*.task7.count}) 
mongodb mongodb-query aggregation-framework
1个回答
0
投票

由于您的字段名称是动态的,因此您无法列出所有动态键:

{ "tasks.project1.task7.count": 1, "tasks.project2.task7.count": 1,  "tasks.project25.task7.count": 1 }

而不是尝试下面的查询,它使用MongoDB的本地aggregation-pipeline

db.collection.aggregate([
    /** Convert `tasks` object into an array ([{k:...,v:...},{k:...,v:...}]) - here we're projecting only `tasks` field */
    {
      $project: { _id: 0, tasks: { $objectToArray: "$tasks" } }
    },
    /** Iterate over tasks array & re-shaping objects inside tasks & forming a new array of [{k:...,v:...},{k:...,v:...}]
     * We're using `arrayToObject` to convert array to object back again
     */
    {
      $project: {
        tasks: {
          $arrayToObject: { 
             $map: { input: "$tasks", in: { "k": "$$this.k", "v": { task7: { count: "$$this.v.task7.count" } } } } 
          }
        }
      }
    }
  ])

Test: mongoplayground

注意:我强烈建议避免使用动态字段名称,该名称在读取或更新现有文档时会导致多个问题。您可以很好地设计数据和应采用的方式-您将以一种首选的方式编写数据,并轻松读取n次,否则,如果您在编写时不相信更好的架构设计,则可以在每次读取时都要执行此乏味的过程,这不是首选方法,而且代价可能很高。

© www.soinside.com 2019 - 2024. All rights reserved.