Если у меня есть следующий объект как obj
:
{
"abc1": "xyz1",
"abc2": "xyz2",
"abc3": "xyz3"
}
и я хочу сделать агрегацию с чем-то вроде:
db.collection.aggregate([
{
"$match": {
"_id": {
$in:
Object.keys(obj)
}
}
},
{
"$lookup": {
"from": "subdocument",
"pipeline": [
{
"$match": {
"_id": ObjectId(matching_value)
}
},
],
"as": "subdocument"
}
},
{ "$unwind": "$subdocument" }
])
Как я могу получить конвейер $lookup
чтобы соответствовать ключу объекта, чтобы соответствовать значению объекта? Является ли это возможным?
Таким образом, это будет единственная версия вызова базы данных:
let obj = {
"abc1": "xyz1",
"abc2": "xyz2",
"abc3": "xyz3"
}
for (let key in obj)
{
db.collection.aggregate([
{
"$match": {
"_id":
ObjectId(key)
}
},
{
"$lookup": {
"from": "subdocument",
"pipeline": [
{
"$match": {
"_id": ObjectId(obj[key])
}
},
],
"as": "subdocument"
}
},
{ "$unwind": "$subdocument" }
])
}
Примеры коллекций
db.maindocuments
[
{
_id: "abc1",
data: "data"
},
{
_id: "abc2",
data: "data"
},
{
_id: "abc3",
data: "data"
}
]
db.subdocuments
[
{
_id: "xyz1",
data: "data"
},
{
_id: "xyz2",
data: "data"
},
{
_id: "xyz3",
data: "data"
}
]
Ну, я вижу, что нет никакого отношения в обеих коллекциях. и именно поэтому $lookup
не будет работать, так как в документах нет соответствующих ключей.
Таким образом, вы можете сделать, используя async
await
const obj = {
"abc1": "xyz1",
"abc2": "xyz2",
"abc3": "xyz3"
}
for (let key in obj) {
const data = await db.collection.findOne({ _id: key })
const subdocument = await db.subdocument.findOne({ _id: obj[key] })
data.subdocument = subdocument
}
_id
для каждого документа?
matching_value
? и что_id
содержит здесь"_id": { $in: Object.keys(obj) }
?matching_value
предназначается , чтобы соответствовать «значение» в объекте в предыдущем абзаце, т.е.xyz1
дляabc1
. Таким образом,$in
будет содержать значения["abc1", "abc2", "abc3"