仅在mongodb中为动态字段名投影嵌套对象
我有一个名为logins的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
{
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" } } } }
}
}
}
}
])