Mongodb 聚合从 2 个数组创建输出为 {"key": "value"}
Mogodb aggregation create output as {"key": "value"} from 2 arrays
我有一个关于如何从 2 个数组创建输出的问题,一个数组带有翻译键,另一个数组带有翻译,我将输出为
"translation_key":"value"
当前输出:
{
"_id" : ObjectId("5bfc0b2b30c4683f585078fb"),
"translation" : [
"hour",
"day"
],
"translation_key" : [
"HOUR_TEXT",
"DAY_TEXT"
],
"locale_id" : "EN_en"
}
输出应该是:
{
"EN_en" :{
"HOUR_TEXT" :"hour",
"DAY_TEXT" :"day",
}
}
您可以使用以下聚合
您可以使用 $range
to get index from both the arrays and can create key (k)
and value (v)
pair for the resultant array and then finally $arrayToObject
将结果数组转换为单个文档。
db.collection.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": [[
{
"k": "$locale_id",
"v": {
"$arrayToObject": {
"$map": {
"input": { "$range": [0, { "$size": "$translation_key" }] },
"in": {
"k": { "$arrayElemAt": ["$translation_key", "$$this"] },
"v": { "$arrayElemAt": ["$translation", "$$this"] }
}
}
}
}
}
]]
}
}}
])
哪个returns
[
{
"EN_en": {
"DAY_TEXT": "day",
"HOUR_TEXT": "hour"
}
}
]
您可以尝试以下聚合:
db.col.aggregate([
{
$project: {
array: [
{
k: "$locale_id",
v: {
$arrayToObject: {
$map: {
input: { $range: [0, { $size: "$translation" }] },
as: "index",
in: {
k: { $arrayElemAt: [ "$translation", "$$index" ] },
v: { $arrayElemAt: [ "$translation_key", "$$index" ] }
}
}
}
}
}
]
}
},
{
$replaceRoot: {
newRoot: { $arrayToObject: "$array" }
}
}
])
基本上您需要使用 $arrayToObject operator to manipulate your key names and in your case it should be used twice. This operator expects an array of objects with two properties k
and v
and therefore you should use $map to generate that values based on translation
, $range is used to generate indexes to traverse translation
and translation_key
arrays. Then you can use $replaceRoot 将动态生成的密钥提升到文档的根级别。
输出:
{ "EN_en" : { "hour" : "HOUR_TEXT", "day" : "DAY_TEXT" } }
我有一个关于如何从 2 个数组创建输出的问题,一个数组带有翻译键,另一个数组带有翻译,我将输出为
"translation_key":"value"
当前输出:
{
"_id" : ObjectId("5bfc0b2b30c4683f585078fb"),
"translation" : [
"hour",
"day"
],
"translation_key" : [
"HOUR_TEXT",
"DAY_TEXT"
],
"locale_id" : "EN_en"
}
输出应该是:
{
"EN_en" :{
"HOUR_TEXT" :"hour",
"DAY_TEXT" :"day",
}
}
您可以使用以下聚合
您可以使用 $range
to get index from both the arrays and can create key (k)
and value (v)
pair for the resultant array and then finally $arrayToObject
将结果数组转换为单个文档。
db.collection.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": [[
{
"k": "$locale_id",
"v": {
"$arrayToObject": {
"$map": {
"input": { "$range": [0, { "$size": "$translation_key" }] },
"in": {
"k": { "$arrayElemAt": ["$translation_key", "$$this"] },
"v": { "$arrayElemAt": ["$translation", "$$this"] }
}
}
}
}
}
]]
}
}}
])
哪个returns
[
{
"EN_en": {
"DAY_TEXT": "day",
"HOUR_TEXT": "hour"
}
}
]
您可以尝试以下聚合:
db.col.aggregate([
{
$project: {
array: [
{
k: "$locale_id",
v: {
$arrayToObject: {
$map: {
input: { $range: [0, { $size: "$translation" }] },
as: "index",
in: {
k: { $arrayElemAt: [ "$translation", "$$index" ] },
v: { $arrayElemAt: [ "$translation_key", "$$index" ] }
}
}
}
}
}
]
}
},
{
$replaceRoot: {
newRoot: { $arrayToObject: "$array" }
}
}
])
基本上您需要使用 $arrayToObject operator to manipulate your key names and in your case it should be used twice. This operator expects an array of objects with two properties k
and v
and therefore you should use $map to generate that values based on translation
, $range is used to generate indexes to traverse translation
and translation_key
arrays. Then you can use $replaceRoot 将动态生成的密钥提升到文档的根级别。
输出:
{ "EN_en" : { "hour" : "HOUR_TEXT", "day" : "DAY_TEXT" } }