gpt4 book ai didi

mongodb - 如何将两个数组连接成一个对象数组

转载 作者:行者123 更新时间:2023-12-03 23:37:56 25 4
gpt4 key购买 nike

在 mongodb 3.4.5 aggregate , 有以下文件:

{id:1, a:['x','y','z'], b:[2,3,4]}

并想将其更改为
{id:1, field: [{a:'x', b:2}, {a:'y', b:3}, {a:'z', b:4}]}

怎么做 aggregate阶段?

我尝试使用 $arrayToObject mongodb 3.4.5 的特性,但不幸的是...

最佳答案

你真的想要 $zip $arrayElemAt $map 这里:

db.collection.aggregate([
{ "$project": {
"field": {
"$map": {
"input": { "$zip": { "inputs": [ "$a", "$b" ] } },
"as": "el",
"in": {
"a": { "$arrayElemAt": [ "$$el", 0 ] },
"b": { "$arrayElemAt": [ "$$el", 1 ] }
}
}
}
}}
])

产生:
{
"field" : [
{
"a" : "x",
"b" : 2
},
{
"a" : "y",
"b" : 3
},
{
"a" : "z",
"b" : 4
}
]
}

$zip “成对”和 $map 使用 $arrayElemAt 处理每一对为新键取每个索引。

作为绝对索引的替代,您可以同时使用 $arrayToObject$objectToArray :
db.collection.aggregate([
{ "$project": {
"field": {
"$map": {
"input": { "$objectToArray": {
"$arrayToObject": {
"$zip": { "inputs": [ "$a", "$b" ] }
}
}},
"as": "el",
"in": { "a": "$$el.k", "b": "$$el.v" }
}
}
}}
])

做同样的事情,但它有点多余,因为 $zip 无论如何都是成对的,所以我们已经知道结果是“成对”的 01索引。

详细的步骤

首先你要 $zip 创建对:
{ "$project": {
"_id": 0,
"field": { "$zip": { "inputs": [ "$a", "$b" ] } }
}}

从每个数组生成“成对”:
{ "field" : [ [ "x", 2 ], [ "y", 3 ], [ "z", 4 ] ] }

$map 从这里应该是不言而喻的,所以我们展示了 $arrayToObject步:
  { "$project": {
"field": { "$arrayToObject": "$field" }
}}

这使得这些数组对变成“键”和“值”:
{ "field" : { "x" : 2, "y" : 3, "z" : 4 } }

然后是 $objectToArray 的变换:
  { "$project": {
"field": { "$objectToArray": "$field" }
}}

这使得一个带有键的对象数组 "k""v" :
{ 
"field" : [
{ "k" : "x", "v" : 2 },
{ "k" : "y", "v" : 3 },
{ "k" : "z", "v" : 4 }
]
}

然后传递给 $map 重命名“键”:
  { "$project": {
"field": {
"$map": {
"input": "$field",
"as": "el",
"in": { "a": "$$el.k", "b": "$$el.v" }
}
}
}}

并给出最终输出:
{ 
"field" : [
{ "a" : "x", "b" : 2 },
{ "a" : "y", "b" : 3 },
{ "a" : "z", "b" : 4 }
]
}

作为单独的管道阶段(您不应该这样做),但对于整个示例:
db.collection.aggregate([
{ "$project": {
"_id": 0,
"field": { "$zip": { "inputs": [ "$a", "$b" ] } }
}},
{ "$project": {
"field": { "$arrayToObject": "$field" }
}},
{ "$project": {
"field": { "$objectToArray": "$field" }
}},
{ "$project": {
"field": {
"$map": {
"input": "$field",
"as": "el",
"in": { "a": "$$el.k", "b": "$$el.v" }
}
}
}}
])

但我没有 MongoDB 3.4 或更高版本

然后,如果您实际上并未将数据用于持续的聚合操作,那么使用几乎任何语言来执行此操作都非常简单。

例如,在 MongoDB shell 中使用 JavaScript 迭代游标:
db.collection.find().map(doc => {
doc.field = doc.a.map((e,i) => [e, doc.b[i]]).map(e => ({ a: e[0], b: e[1] }));
delete doc.a;
delete doc.b;
return doc;
})

做完全相同的事情并且与初始聚合函数示例中执行的操作相同。

现代 shell 版本或其他 JavaScript 引擎(您甚至可以将其与较旧的 MongoDB 版本一起使用)可以更清晰地做到这一点:
db.collection.find().map(({ a, b }) => 
({ field: a.map((e,i) => [e, b[i]]).map(([a,b]) => ({ a, b })) })
)

或者坦率地说只是..
db.collection.find().map(({ a, b }) =>
({ field: a.map((a,i) => ({ a, b: b[i] })) })
)

由于实际上没有必要复制您需要对聚合框架执行的所有步骤,因为您可以直接通过匹配索引转置数组元素。

关于mongodb - 如何将两个数组连接成一个对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44613722/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com