3

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

1 Answer 1

3

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" 
        ] 
    }} 
])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.