The user collection in my MongoDB database needs to be searched to find content for my users. Each user has their list of blocked users.
const suggested_content = await db.collection('users').find({
_id: { $nin: [...blockedUsers] }
}).toArray();
So the question is, in what ballpark should the maximum number of elements of the blockedUsers array be in? In other words, at about what number of elements will performing a $lookup
to find and remove the block users be faster instead?
The user collection in my MongoDB database needs to be searched to find content for my users. Each user has their list of blocked users.
const suggested_content = await db.collection('users').find({
_id: { $nin: [...blockedUsers] }
}).toArray();
So the question is, in what ballpark should the maximum number of elements of the blockedUsers array be in? In other words, at about what number of elements will performing a $lookup
to find and remove the block users be faster instead?
- 2 Do you really expect your users will block hundreds or even thousands of users? – Wernfried Domscheit Commented Mar 25 at 6:02
- @WernfriedDomscheit The question is simplified. In addition to blocked users, there will also be viewed users. Viewed users also need to be removed so as not to show duplicate content. – Bear Bile Farming is Torture Commented Mar 25 at 6:07
- 2 Welcome back, I was starting to miss your questions which are always a bit special. As a general suggestion I would propose to read this article: mongodb/blog/post/building-with-patterns-a-summary It will answer many of your concerns and you get out many ideas from it. – Wernfried Domscheit Commented Mar 25 at 6:07
1 Answer
Reset to default 3An "in-array" check will always* be faster than a
$lookup
. Since it's part of the query.- Unless you're trying to compare arrays with 1 million elems vs just 1 lookup matching a single elem. Where that crossover occurs, you'll need to performance test yourself.
Your query also needs to exclude the current user id. Assuming they can't block themselves, you probably don't want to recommend their own content to them.
find({ _id: { $nin: [currentUserId, ...blockedUsers] } }
. If the user is not signed in, there won't be any blockedUsers to check.The limitation here is more likely to be the size of the array growing so large that the document itself is larger than the 16 MB limit.
The recommended size for arrays containing documents is 200-1000 elements - that's specific to querying/filtering/indexing performance with the elements in the array. Arrays which can keep growing should be split out into their own collection, with each each document having N elements. And then you'll need to use a lookup. This is roughly the Subset Pattern.
- The recommended max elems-per-array recommendation is not clearly documented. However, it does come up in MongoDB's Data modeling vids, like this one which says 1000.
- (Will look for the vid which says 200)
- Schema Design Anti-Patterns: Avoid Unbounded Arrays