Having a rough time trying to get this query correct. I need to match against a string that is coming through as params from express. The problem is that it can be a string value or an ObjectId. True problem is that Mongoose doesn't cast strings to ObjectId's automatically, so I have to do that part. Here's what I have so far:
{
$match: {
$or: [
{
slug: data.product,
},
{
_id: mongoose.Types.ObjectId.isValid(data.product)
? [mongoose.Types.ObjectId(data.product)]
: [],
},
],
},
},
/products/:product
is my route/products/stream
works/products/5cf4530c1b5c884fbf2298e5
fails
My full aggregation pipeline looks like this:
[
{
$match: {
$or: [
{
slug: data.product,
},
{
_id: mongoose.Types.ObjectId.isValid(data.product)
? [mongoose.Types.ObjectId(data.product)]
: [],
},
],
},
},
{
$lookup: {
from: 'products',
localField: '_id',
foreignField: '_id',
as: 'product',
},
},
{
$lookup: {
from: 'ratings',
localField: '_id',
foreignField: 'product',
as: 'rating',
},
},
{
$lookup: {
from: 'categories',
localField: 'categories',
foreignField: '_id',
as: 'category',
},
},
{
$unwind: {
path: '$rating',
preserveNullAndEmptyArrays: true,
},
},
{
$unwind: {
path: '$product',
preserveNullAndEmptyArrays: true,
},
},
{
$unwind: {
path: '$category',
preserveNullAndEmptyArrays: true,
},
},
{
$group: {
_id: '$product._id',
product: {
$first: {
_id: '$product._id',
name: '$product.name',
url: '$product.url',
slug: '$product.slug',
logo: '$product.logo',
tagline: '$product.tagline',
description: '$product.description',
images: '$product.images',
roles: '$product.roles',
updated: '$product.updatedAt',
created: '$product.createdAt',
},
},
categories: {
$addToSet: {
_id: '$category._id',
name: '$category.name',
image: '$category.image',
},
},
ratings: {
$first: {
total: {
$sum: 1,
},
score: {
$sum: '$rating.rating',
},
sentiment: {
$sum: '$rating.sentiment',
},
},
},
},
},
]
Any thoughts? The docs aren't helping me out much. Thanks in advance!