Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅在mongodb中为动态字段名投影嵌套对象_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

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

仅在mongodb中为动态字段名投影嵌套对象,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个名为logins的mongodb集合。结构如下: { id: 1, name: "N1", tasks: { project1: { task7: { count: 10 time: 1.2 }, task3: { count: 56 time: 1050 } }, project25: { task7: { co

我有一个名为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”的详细信息,而不考虑“project”级别。像下面这样的,可能吗

db.logins.find({tasks.*.task7.count}) 

由于字段名是动态的&您无法列出所有动态键:

{ "tasks.project1.task7.count": 1, "tasks.project2.task7.count": 1,  "tasks.project25.task7.count": 1 }
请尝试以下使用MongoDB本机的查询:

测试:


注意:我强烈建议在阅读或更新现有文档时避免使用动态字段名,因为动态字段名会导致一些问题。您的数据设计得非常好&它应该是这样的-您将以首选方式编写一次并轻松地读取n次,否则,如果您在编写时不相信更好的模式设计,那么您必须在每次读取时都执行此繁琐的过程,这不是首选的,而且成本可能会很高

我认为您的模式结构不正确。您可以直接使用如下命令:
{“tasks.project25.task7.count”:1}
。但是,是的,您的模式不正确。进一步查询将非常困难。您的密钥需要在每个文档中都相似,但当前每个密钥在tasks对象中都不同。我只是此数据库的用户。我无法控制模式设计。但根据我们的业务,我可以理解,关键需要是动态的。无论如何,谢谢你的回复。干杯…谢谢,这是一个很好的解决方案。是否有一种方法可以展平阵列,使我只能看到没有嵌套对象的结果。就像在纯文本文件中一样。@Niluparasinghe:你是说像这样:?如果是,您所需要的不是在
v
处创建对象
task7.count
,而是将其替换为
v
,部分替换为::
“v”:“$$this.v.task7.count”
。是这样的。但是我看到如果文档中没有“task7”,那么它将给出一个错误。这是否意味着在所有文档中都必须具有该密钥。因为在实际情况中,有些文档没有“task7”。@NilupaRupasinghe:那么您想只投影具有
task7
项目吗?试试这个:是的,这个有效。非常感谢你的回答,我还有很多东西要学。
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" } } } } 
          }
        }
      }
    }
  ])