node.js - MongoDB - 查询 ObjectId 嵌套数组
问题描述
我在 MongoDB 上有一个名为 Product 的集合,其中包含一些文档,这是一个示例:
{
_id: 'xxxxxx',
name: 'cellphone',
brands: [
'aaaaaa',
'bbbbbb'
]
}
'brands' 键引用了另一个名为 Brand 的集合,例如:
[
{
_id: 'aaaaaa',
name: 'Apple',
_deprecatedDate: null
},
{
_id: 'bbbbbb',
name: 'BlackBerry',
_deprecatedDate: '2016-07-13T02:27:17.724Z'
}
]
因此,使用产品 ID,我想获得所有未弃用的品牌。我发现这样做的唯一方法是使用以下代码:
let _product = await Product.findOne({ _id: 'xxxxxx' });
return Brand.find({ _id: { $in: _product.brands }, _deprecatedDate: null });
有没有办法用一个查询来做到这一点?
解决方案
您可以使用$lookup从多个集合中获取数据.aggregate()
。您可以指定自定义(MongoDB 3.6):pipeline
Product.aggregate([
{
$lookup: {
from: "Brand",
let: { brands: "$brands" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $in: [ "$_id", "$$brands" ] },
{ $eq: [ "$_deprecatedDate", null ] }
]
}
}
}
],
as: "brands"
}
}
])
或者只是在下一阶段使用 $filter 来过滤掉不推荐使用的$lookup
品牌:
Product.aggregate([
{
$lookup: {
from: "Brand",
localField: "brands",
foreignField: "_id",
as: "brands"
}
},
{
$addFields: {
brands: {
$filter: {
input: "$brands",
as: "brand",
cond: {
$eq: [ "$$brand._deprecatedDate", null ]
}
}
}
}
}
])
推荐阅读
- ios - 谷歌 iOS 设备策略不能很好地与使用谷歌 SSO 的 iOS 应用程序配合使用
- vimeo - 如果视频上传成功,是否有任何回调选项用于通知?
- node.js - 在 Docker 上安装 npm 得到错误不支持 Node.js v13
- binary - 创建一个 dvar 布尔约束
- typescript - 如何过滤父类型以便在 TypeScript 中选择给定类型的子类型?
- python - 如何使用 groupby + stack 获得相当于 pandas 的融化?
- c++ - 如何从 TBB concurrent_hash_map C++ 中迭代和擦除
- c++ - 为什么在这段代码中使用 auto 和 int 会给出不同的答案?
- python - 创建 dask_jobqueue 调度程序以在自定义 HPC 上启动
- python - 需要使用 argparse 传递带单引号的字符串参数