#mongodb #aggregation-framework
Вопрос:
Мне нужно проанализировать некоторые коллекции баз данных mongo. Что мне нужно, чтобы извлечь имена и значения коллекции.
Вот как далеко я продвинулся:
db.collection(coll.name)
.aggregate([
{ $project: { arrayofkeyvalue: { $objectToArray: '$ROOT' } } },
{ $unwind: '$arrayofkeyvalue' },
{
$group: {
_id: null,
allkeys: { $addToSet: '$arrayofkeyvalue.k' },
},
},
])
.toArray();
Это работает довольно хорошо. Я получаю все ключи. Однако я бы тоже хотел получить значения.
Итак, я подумал «кусок пирога» и заменил allkeys
раздел allkeysandvalues
разделом, который должен создавать карту с парами ключей и значений.
Подобный этому:
db.collection(coll.name)
.aggregate([
{ $project: { arrayofkeyvalue: { $objectToArray: '$ROOT' } } },
{ $unwind: '$arrayofkeyvalue' },
{
$group: {
_id: null,
allkeysandvalues: {
$map: {
input: '$arrayofkeyvalue',
as: 'kv',
in: {
k: '$kv.k',
v: '$kv.v',
},
},
},
},
},
])
.toArray();
Но это не работает. Я получаю сообщение об ошибке
MongoError: unknown group operator '$map'
Кто-нибудь знает, как это решить?
Комментарии:
1. Можете ли вы добавить mongoplayground.net ссылка с образцами данных, вы не можете использовать $map внутри $группы.
Ответ №1:
Этап конвейера $group требует выражения аккумулятора, поэтому вам нужно использовать $push вместо $map
:
{
$group: {
_id: null,
allkeysandvalues: {
$push: "$arrayofkeyvalue"
}
}
}
или
{
$group: {
_id: null,
allkeysandvalues: {
$push: {
k: "$arrayofkeyvalue.k",
v: "$arrayofkeyvalue.v"
}
}
}
}
что возвращает тот же результат.
Пожалуйста, обратите внимание, что arrayofkeyvalue
это объект, так как вы запускали $unwind
его до $group
Ответ №2:
Ошибка пользователя: неизвестный оператор группы «$карта»
Вы не можете использовать $map
оператор на $group
этапе непосредственно на корневом уровне,
вы можете попробовать добавить еще один групповой этап,
$group
по k (ключу) и получите первое v (значение)$group
по null и постройте массив пары ключ-значение$arrayToObject
преобразование массива пар ключ-значение в объект
db.collection(coll.name).aggregate([
{ $project: { arrayofkeyvalue: { $objectToArray: "$ROOT" } } },
{ $unwind: "$arrayofkeyvalue" },
{
$group: {
_id: "$arrayofkeyvalue.k",
value: { $first: "$arrayofkeyvalue.v" }
}
},
{
$group: {
_id: null,
allkeysandvalues: { $push: { k: "$_id", v: "$value" } }
}
},
{ $project: { allkeysandvalues: { $arrayToObject: "$allkeysandvalues" } } }
])
Комментарии:
1. Оба ответа были одинаковыми и правильными. Я должен был выбрать один из них в качестве правильного ответа и выбрал тот, который пришел быстрее. Я все еще благодарен вам за краткое объяснение. Спасибо!