#mongodb #mongoose
#mongodb #mongoose
Вопрос:
У меня есть три схемы, назовите их A, B и C.
Все схемы имеют автоматически сгенерированные _id
поля , name
, и active
. Но C имеет дополнительное поле relations
, которое представляет собой объект с двумя полями в нем a_id
, и b_id
. Что-то вроде этого:
{
_id,
name,
active,
relations: {
a_id,
b_id
}
}
Что я хотел бы запросить все документы из C, где соответствующие документы A и B оба активны. Поэтому замените идентификаторы: a_id
, и b_id
фактическими соответствующими документами.
Что-то вроде: C.findMany({ 'relations.a_id': true, 'relations.b_id': true })
Как я могу это сделать?
Ответ №1:
Попробуйте запрос агрегации,
$lookup
с коллекцией передайтеa_id
в let в соответствии$match
с условием проверки конвейераa_id
и активным статусомtrue
$lookup
с коллекцией B передайтеb_id
в let в соответствии$match
с условием проверки конвейераb_id
и активным статусомtrue
$project
чтобы отобразить обязательные поля,$arrayElemAt
чтобы получить первый элемент из возвращаемого результата поиска, проверьте, имеет ли он значение null$ifNull
, тогда он вернет тот же идентификатор
C.aggregate([
{
$lookup: {
from: "A",
let: { id: "$relations.a_id" },
pipeline: [{
$match: {
active: true,
$expr: { $eq: ["$id", "$_id"] }
}
}],
as: "relations.a_data"
}
},
{
$lookup: {
from: "B",
let: { id: "$relations.b_id" },
pipeline: [{
$match: {
active: true,
$expr: { $eq: ["$id", "$_id"] }
}
}],
as: "relations.b_data"
}
},
{
$project: {
name: 1,
active: 1,
relations: {
a_id: {
$ifNull: [
{ $arrayElemAt: ["$relations.a_data", 0] },
"$relations.a_id"
]
},
b_id: {
$ifNull: [
{ $arrayElemAt: ["$relations.b_data", 0] },
"$relations.b_id"
]
}
}
}
}
])
Комментарии:
1. Если я запускаю игровую площадку (с благодарностью, спасибо), он возвращает только идентификатор для B. Для вас это то же самое? Если нет, то почему?
2. активный статус — false
b_id: 2
записи в коллекции B.