Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select documents where all values in an array field exist in another array

I wasn't quite sure how to title this!

So I have an array of product IDs

var productIds = [139,72,73,1,6]

And a bunch of customer documents in MongoDB

{
    name: 'James',
    products: [ 73, 139 ],
    _id: 5741cff3f08e992598d0a39b
}

{
    name: 'John',
    products: [ 72, 99 ],
    _id: 5741d047f08e992598d0a39e
}

I would like to find customers when all of their products appear in the array of product IDs (productIds)

I tried:

'products' : {
    '$in': productIds
}

But that returns John, even though 99 doesn't exist in the list of product IDs

I also tried:

'products' : {
    '$all': productIds
}

Which returns nothing because none of the customer have ALL the products

Is there a way to achieve what I need in a single query or am I going to have to do some post query processing?

I also tried

'products': {
    '$in': productIds,
    '$not': {
        '$nin': productIds
    }
}

but this also seems to return customers when not all product IDs match

like image 262
michael Avatar asked Jan 28 '26 20:01

michael


1 Answers

You can do this using the .aggregate() method and the $redact operator. In your $cond expressions you need to use the $setIsSubset in order to check if all the elements in the "products" array are in "productIds". This is because you cannot use $in in the conditional expression

var productIds = [139,72,73,1,6];
db.customers.aggregate([ 
    { "$redact": { 
        "$cond": [ 
            { "$setIsSubset": [ "$products", productIds ] },
            "$$KEEP",
            "$$PRUNE" 
        ] 
    }} 
])
like image 125
styvane Avatar answered Jan 30 '26 10:01

styvane



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!