mongodb - 如何在 MongoDB 中的 $lookup 文档上编写 $match
问题描述
我有两个如下所示的 MongoDB 集合:
Products Specials
---------- ----------
_id _id
name product_id
country zip
price percent_discount
out_of_stock
我也在使用 GraphQL,所以我编写了一个聚合管道,以这种结构返回数据:
specials {
_id
product {
_id
name
country
price
}
zip
percent_discount
out_of_stock
}
我写的这个聚合管道效果很好,看起来像这样:
let response = await Specials.aggregate([
{
$lookup: {
from: 'products',
localField: 'product_id',
foreignField: '_id',
as: 'product'
}
},
{
$unwind: '$product'
},
{
$match: {
zip: zip
}
}
])
return response;
现在我正在尝试在其中添加一个过滤器。过滤器应与产品集合中的名称或国家/地区匹配,最好使用正则表达式。所以我试着写这样的东西,但是当应该只有 2-3 个时它会产生超过 8000 个结果:
let response = await Specials.aggregate([
{
$match: { zip: zip }
},
{
$lookup: {
from: "products",
let: { product_id: "$product_id" },
pipeline: [
{
$match: {
$expr: {
$and: [
{
_id: "$$product_id"
},
{
$or: [
{
name: filter
},
{
country: filter
}
]
}
]
}
}
}
],
as: "product"
}
},
{
$unwind: "$product"
}
])
解决方案
如果您使用的是 Mongo 4.2+ 版,则可以使用$regexMatch
let response = await Specials.aggregate([
{
$lookup: {
from: "products",
let: { product_id: "$product_id" },
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: ["$$product_id", "$_id"]
},
{
$or: [
{
$regexMatch: { input: "$name", regex: filterRegex }
},
{
$regexMatch: { input: "$country", regex: filterRegex }
}
]
}
]
}
}
}
],
as: "product"
}
},
{
$unwind: "$product"
},
{
$match: {
$and: [
{
zip: zip
}
]
}
}
])
return response;
推荐阅读
- python - 如何在不重新启动机器的情况下修复 torch.cuda.is_available() False 问题?
- python - 当函数需要大数据结构作为参数时,如何有效地使用 Pool.starmap?
- vue.js - 如何以编程方式滚动元素而不是 vuetify 中的页面
- java - 为什么在 rDao.insert(log) 处出现未处理的 SQL 异常?
- google-cloud-platform - 如何为 GKE Ingress 分配静态 IP?
- python-3.x - Python:函数调用中的重复序列
- bash - 识别在 shell 中触发的并行进程的结束时间戳
- javascript - Javascript 循环中的 Promise
- javascript - 无法使用 puppeteer 导出异步功能
- c++ - 运行此程序时,我的 If 语句被跳过