#python #mongodb #mongodb-query #aggregation-framework #pymongo
Вопрос:
Я использую Pymongo для запуска агрегатных трубопроводов против нашего Mongodb.
У меня есть следующие коллекции:
Пользователи
{
_id: 1,
name: 'John Doe',
age: 30
},
{
_id: 2,
name: 'Jane Doe',
age: 20
}
Адреса
{
_id: 10,
name: 'Miami'
},
{
_id: 20,
name: 'Orlando'
}
Контакты
{
_id: 100,
contacts: [
{
user_id: 1,
location_id: 10,
},
{
user_id: 2,
location_id: 20,
}
]
}
В результате агрегатного конвейера мне нужно:
{
_id: 100,
contacts: [
{
user_id: 1,
user_name: 'John Doe',
user_age: 30,
location_id: 10,
location_name: 'Miami'
},
{
user_id: 2,
user_name: 'Jane Doe',
user_age: 20,
location_id: 20,
location_name: 'Orlando'
}
]
}
Я попробовал несколько запросов с использованием «$lookup», но я просто получаю новый массив вместо того, чтобы помещать значения в один и тот же массив/объект.
Как я могу получить желаемый результат ?
Ответ №1:
Вы можете использовать этот запрос агрегации:
- Сначала
$unwind
нужно деконструировать массив и получить значения для объединения - Затем два
$lookup
, чтобы объединить значения и создать массивыusers
иlocations
. - Поскольку
_id
используется значение из массива, которое вы хотите, является первым (это должно быть только одно значение, но если существует несколько повторяющихся значений), поэтому вы можете использовать$arrayElemAt
. - Затем
$project
, чтобы получить имя поля, которое вы хотите. - И
$group
перегруппировать ценности.
db.contacts.aggregate([
{
"$unwind": "$contacts"
},
{
"$lookup": {
"from": "users",
"localField": "contacts.user_id",
"foreignField": "_id",
"as": "users"
}
},
{
"$lookup": {
"from": "locations",
"localField": "contacts.location_id",
"foreignField": "_id",
"as": "locations"
}
},
{
"$set": {
"users": {
"$arrayElemAt": [
"$users",
0
]
},
"locations": {
"$arrayElemAt": [
"$locations",
0
]
}
}
},
{
"$project": {
"contacts": {
"user_id": 1,
"location_id": 1,
"user_name": "$users.name",
"user_age": "$users.age",
"location_name": "$locations.name"
}
}
},
{
"$group": {
"_id": "$_id",
"contacts": {
"$push": "$contacts"
}
}
}
])
Пример здесь