我正在尝试在对db.eval()的调用中执行db.collection.aggregate()查询。我使用eval()是因为要进行动态查找,因此我通过串联相关字符串来生成查询。当我手动删除字符串中的引号时,查询工作完美:
await db.collection('Products').aggregate([{
$lookup: {
from: 'Golomax',
localField: 'barcode',
foreignField: 'barcode',
as: 'Golomax'
}
}, {
$unwind: {
path: '$Golomax',
preserveNullAndEmptyArrays: true
}
}, {
$lookup: {
from: 'Masivos SA',
localField: 'barcode',
foreignField: 'barcode',
as: 'Masivos SA'
}
}, {
$unwind: {
path: '$Masivos SA',
preserveNullAndEmptyArrays: true
}
}, {
$out: 'Output'
}]).toArray();
不幸的是,当我在对db.eval()的调用中使用字符串时,它不起作用。我在上面的代码片段两边加上了引号,并将字符串设置为等于变量“ query”,然后尝试了以下方法:
db.eval('async function(){' + query + ' return;}', function(err, result) {
console.log('the result is: ', result);
});
我也尝试过删除“异步”一词,但这仍然没有用。如何确保函数在返回之前完成聚合?谢谢。
-编辑-
我刚刚注意到db.eval()已被弃用并计划删除。另一种选择是“使用普通的MongoDB查询语言和客户端驱动程序API来实现等效的查询/操作”。如何使用字符串查询来做到这一点?
答案 0 :(得分:0)
我刚刚使用Javascript eval()解决了自己的问题,并删除了字符串开头的“ await”。现在执行完美!
答案 1 :(得分:0)
您不需要$eval
。听起来您想为数组中的每个项目创建一个$lookup
和$unwind
。这正是map()
的目的。您可以创建单独的命令数组,然后将其传递给aggregate()
:
// Have a list of places
const thingsToUnwind = [
'Golomax',
'Masivos SA',
'Some Other Place',
'Yet Another Place'
];
const unwindables = thingsToUnwind
// Create a $lookup and $unwind for each place
.map(place => {
return [{
$lookup: {
from: place,
localField: 'barcode',
foreignField: 'barcode',
as: place
}
},
{
$unwind: {
path: `$${place}`,
preserveNullAndEmptyArrays: true
}
}
];
})
// Flatten the array of arrays
.reduce((acc, curr) => [...acc, ...curr], []);
// Add an $output node
unwindables.push({
$out: 'Output'
});
// Perform the aggregation
await db
.collection('Products')
.aggregate(unwindables)
.toArray();