Динамически добавлять ключи из содержимого массива

63
8

Как я могу динамически добавлять поля в MongoDB? У меня есть массив, с которым я хочу создавать столбцы. Например, из этого,

/* 1 */
{
"date" : "2017-07-30",
"brand" : [
{
"name" : "Apple",
"quantity" : 31
}
],
"total" : 31
}

/* 2 */
{
"date" : "2017-08-02",
"brand" : [
{
"name" : "Apple",
"quantity" : 1
},
{
"name" : "Samsung",
"quantity" : 6
}
],
"total" : 7
}

Я хочу это сделать,

/* 1 */
{
"date" : "2017-07-30",
"Apple": 31,
"Samsung": 0,
"total" : 31
}

/* 2 */
{
"date" : "2017-08-02",
"Apple": 1,
"Samsung": 6,
"total" : 7
}

Там $addFields оператор может добавить поле, но как я могу использовать его для нескольких полей?

спросил(а) 2021-01-25T19:12:50+03:00 4 месяца, 3 недели назад
1
Решение
125

Вы можете это сделать, но, честно говоря, это пустая трата. Используйте $replaceRoot и $arrayToObject где у вас есть:

db.collection.aggregate([
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$concatArrays": [
[{ "k": "date", "v": "$date" }],
{ "$map": {
"input": "$brand",
"as": "b",
"in": { "k": "$$b.name", "v": "$$b.quantity" }
}},
[{ "k": "total", "v": "$total" }]
]
}
}
}}
])

На самом деле гораздо проще просто преобразовать из курсора. Как и в оболочке:

db.collection.find().map( doc =>
Object.assign(
{ date: doc.date },
doc.brand.map(d => ({ [d.name]: d.quantity }) )
.reduce((acc,curr) => Object.assign(acc,curr),{}),
{ total: doc.total }
)
)

Что делает то же самое:

[
{
"date" : "2017-07-30",
"Apple" : 31.0,
"total" : 31.0
},
{
"date" : "2017-08-02",
"Apple" : 1.0,
"Samsung" : 6.0,
"total" : 7.0
}
]

ответил(а) 2021-01-25T19:12:50+03:00 4 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема