主要任务:为产品应用标签过滤器(可以是一个或多个)。
需要返回过滤后的产品列表与指定的饮食标签查询。产品标签字段是对标签集合的引用。
$lookup和相关阶段:
{
$lookup: {
from: 'tags',
localField: 'tags',
foreignField: '_id',
as: 'tags',
pipeline: [
{
$project: {
tags: '$tags',
_id: 0,
},
},
],
},
},
{ $unwind: { path: '$tags', preserveNullAndEmptyArrays: true } },
{
$addFields: {
tags: '$tags.tags',
},
},
如果tags集合有ref tags id,则输出产品。否则标签字段不存在。
{
"_id": "65543472bde41c7561151fd3",
"slug": "green-olives",
"name": "Green Olives",
"description": "Some description",
"category": "food-cupboard",
"subCategory": "canned-vegetables"
"popularity": 76,
"views": 327,
"rating": 5,
"tags": {
"dietaries": [
"HALAL"
],
"promotions": [
"PWP"
]
},
}
预期的(虚拟的)聚合$match阶段:
{
$match: {
// if query "tags" exist => filter products which have (tags.dietaries) with query values
// if query "tags" doesn't exist => all product with tags field and without it
}
}
尝试用正则表达式匹配'tags.dietaries'数组,如果dietary(查询)存在,否则返回所有。问题是产品返回,但只有现有的标签字段。
{
$match: {
'tags.dietaries': dietary
? {
$regex: dietary.split('+').join('|'),
}
: /.*/,
},
},
另一个想法是使用$cond运算符,但不能正确应用它。
此外,我还认为默认情况下保持标签字段为空,这样就可以/改进匹配标签。这是个好主意吗
如果能帮上忙我会很感激的。
2条答案
按热度按时间ahy6op9u1#
根据我的理解,我做了这个聚合,
我冒昧地删除了放松阶段,因为我没有看到它的用途,我注意到,你有一个一对一的关系,所以我只是采取了第一个项目。
如果我正确理解了你的过滤标准,你想通过dietaries过滤,如果标签可用,如果不只是返回所有内容,
我希望我的理解是对的,如果不给我留下一些评论,所以我们可以调整聚合。
我希望这对你有帮助
z2acfund2#
看起来像拐杖,但工作正常。
产品描述:
1.如果查询存在('HALAL +GLUTEN_FREE'),则返回'tags.dietaries'标签数组包含查询标签数组之一的文档:
$in: dietary ? dietary.split('+')
1.否则返回'tags.dietaries'字段存在但不存在的文档:
: [null, /.*/]
谢谢Abdellatif Sraiti的帮助。他把我带到了正确的方向。
希望能帮助别人。
P.S.如果有人能分享一个更好的解决方案,我将不胜感激。