Skip to content
This repository was archived by the owner on Sep 10, 2025. It is now read-only.

Commit 5fb421f

Browse files
updated
1 parent 795f62c commit 5fb421f

4 files changed

Lines changed: 109 additions & 112 deletions

File tree

body.txt

Lines changed: 65 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,75 @@
11

2-
This challenge involves styling a nested, unordered list using Tailwind CSS to create a visually appealing and organized hierarchical structure. The goal is to visually distinguish between the different levels of nesting and create a clean, readable list.
3-
4-
5-
**Description of the Styling:**
6-
7-
We will create a multi-level nested list where each level has distinct styling. The top-level list items will have a larger font size and a different background color than subsequent levels. Indentation will be used to clearly show the hierarchy, and we'll use Tailwind's utility classes to achieve this efficiently. We will also add some subtle hover effects for improved user experience.
8-
9-
**Full Code:**
10-
11-
```html
12-
<ul class="list-disc pl-6">
13-
<li class="mb-2 bg-gray-100 p-2 rounded text-lg font-medium">
14-
Level 1 Item 1
15-
<ul class="list-disc pl-6">
16-
<li class="mb-2 bg-gray-200 p-2 rounded hover:bg-gray-300">Level 2 Item 1</li>
17-
<li class="mb-2 bg-gray-200 p-2 rounded hover:bg-gray-300">
18-
Level 2 Item 2
19-
<ul class="list-disc pl-6">
20-
<li class="mb-2 bg-gray-300 p-2 rounded hover:bg-gray-400">Level 3 Item 1</li>
21-
<li class="mb-2 bg-gray-300 p-2 rounded hover:bg-gray-400">Level 3 Item 2</li>
22-
</ul>
23-
</li>
24-
</ul>
25-
</li>
26-
<li class="mb-2 bg-gray-100 p-2 rounded text-lg font-medium">Level 1 Item 2</li>
27-
</ul>
2+
## Description of the Error
3+
4+
One common performance bottleneck in MongoDB applications stems from the overuse of the `$in` operator, particularly with large arrays. When querying documents using `$in` with a very large array of values, MongoDB can experience significant performance degradation. This is because the query effectively needs to scan a large portion of the collection to find matching documents, making it inefficient, especially without an appropriate index. This leads to slow query times and high resource consumption on the MongoDB server.
5+
6+
## Code Example & Fixing Steps
7+
8+
Let's assume we have a collection named `products` with documents like this:
9+
10+
```json
11+
{ "_id" : ObjectId("650b72764d5a3a468b46f0d4"), "category": "electronics", "name": "Laptop", "tags": ["laptop", "computer", "electronics"] }
12+
{ "_id" : ObjectId("650b728a4d5a3a468b46f0d5"), "category": "clothing", "name": "Shirt", "tags": ["shirt", "clothing", "fashion"] }
13+
{ "_id" : ObjectId("650b729e4d5a3a468b46f0d6"), "category": "electronics", "name": "Phone", "tags": ["phone", "mobile", "electronics"] }
14+
```
15+
16+
And we want to find products with tags within a large array:
17+
18+
```javascript
19+
// Inefficient query
20+
db.products.find({ tags: { $in: ["laptop", "computer", "electronics", "shirt", "clothing", "fashion", "phone", "mobile", ... (many more tags)] } });
21+
```
22+
23+
This query will be slow with a large `$in` array.
24+
25+
**Fixing the problem:**
26+
27+
1. **Create an Index:** The most effective solution is to create an index on the `tags` field. However, simply indexing `tags` isn't ideal for this use-case due to the nature of the `$in` query. Using a compound index won't help. A better approach is to restructure the data.
28+
29+
2. **Data Restructuring:** Instead of storing tags as an array, consider creating separate collections for products and tags with a many-to-many relationship. This involves creating a new collection, say `productTags`, that links products to tags:
30+
31+
32+
```json
33+
// products collection (simplified)
34+
{ "_id" : ObjectId("650b72764d5a3a468b46f0d4"), "category": "electronics", "name": "Laptop" }
35+
{ "_id" : ObjectId("650b728a4d5a3a468b46f0d5"), "category": "clothing", "name": "Shirt" }
36+
37+
// productTags collection
38+
{ "product_id": ObjectId("650b72764d5a3a468b46f0d4"), "tag": "laptop" }
39+
{ "product_id": ObjectId("650b72764d5a3a468b46f0d4"), "tag": "computer" }
40+
{ "product_id": ObjectId("650b72764d5a3a468b46f0d4"), "tag": "electronics" }
41+
{ "product_id": ObjectId("650b728a4d5a3a468b46f0d5"), "tag": "shirt" }
42+
// ...and so on
43+
```
44+
45+
3. **Efficient Query:** Now, you can query efficiently using `$in` on the `tag` field within the `productTags` collection and then use aggregation to get the products.
46+
47+
```javascript
48+
db.productTags.aggregate([
49+
{ $match: { tag: { $in: ["laptop", "computer", "electronics", "shirt", "clothing", "fashion", "phone", "mobile", ... ] } } },
50+
{ $group: { _id: "$product_id", tags: { $push: "$tag" } } },
51+
{ $lookup: {
52+
from: "products",
53+
localField: "_id",
54+
foreignField: "_id",
55+
as: "product"
56+
} },
57+
{ $unwind: "$product"},
58+
{ $project: { _id: "$product._id", name: "$product.name", category: "$product.category", tags: 1, _id:0} }
59+
])
60+
2861
```
2962

30-
**Explanation:**
3163

32-
* **`list-disc`:** This Tailwind class adds a disc bullet point to the list items.
33-
* **`pl-6`:** This adds padding to the left, creating the indentation for each nesting level. The amount of padding increases with each level.
34-
* **`mb-2`:** Adds a margin to the bottom of each list item for spacing.
35-
* **`bg-gray-100`, `bg-gray-200`, `bg-gray-300`:** These provide different shades of gray backgrounds to visually distinguish the levels. The shade deepens with each level.
36-
* **`p-2`:** Adds padding to each list item for better readability.
37-
* **`rounded`:** Adds rounded corners to the list items.
38-
* **`text-lg font-medium`:** Styles the text of the top-level list items.
39-
* **`hover:bg-gray-300`, `hover:bg-gray-400`:** Adds a hover effect, changing the background color on hover to provide visual feedback.
64+
## Explanation
4065

66+
The original `$in` query against an array field forces a collection scan because an index can't efficiently utilize the array structure for such searches. By restructuring the data and creating a new collection with a more suitable schema, we can leverage indexes and utilize efficient queries, significantly improving performance, especially when dealing with a large number of tags and products. The aggregate query filters for relevant tags in `productTags` and then joins the data back to the `products` collection to retrieve the product information. This avoids the costly collection scan.
4167

42-
**Links to Resources to Learn More:**
68+
## External References
4369

44-
* **Tailwind CSS Documentation:** [https://tailwindcss.com/docs](https://tailwindcss.com/docs) (Comprehensive documentation on all Tailwind CSS classes and utilities)
45-
* **CSS Nested Lists Tutorial:** (Search for "CSS nested lists" on your preferred learning platform like freeCodeCamp, MDN Web Docs, etc. Many tutorials are available.)
70+
* [MongoDB Indexing Documentation](https://www.mongodb.com/docs/manual/indexes/)
71+
* [MongoDB Aggregation Framework](https://www.mongodb.com/docs/manual/aggregation/)
72+
* [Optimizing MongoDB Queries](https://www.mongodb.com/blog/post/optimizing-mongodb-queries-for-performance)
4673

4774

4875
Copyrights (c) OpenRockets Open-source Network. Free to use, copy, share, edit or publish.

errors/javascript/mongodb-overuse-of-in-operator-leading-to-performance-degradation/README.md

Lines changed: 42 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -3,106 +3,76 @@
33

44
## Description of the Error
55

6-
A common performance bottleneck in MongoDB applications arises from the overuse of the `$in` operator in queries, especially when used with a very large array. The `$in` operator, while convenient for querying documents where a field matches any value within a specified array, can lead to significant performance degradation if the array is excessively long. This happens because MongoDB needs to perform a separate lookup for each element in the array, resulting in a potentially large number of index scans. This drastically impacts query execution time, especially on large collections.
6+
One common performance bottleneck in MongoDB applications stems from the overuse of the `$in` operator, particularly with large arrays. When querying documents using `$in` with a very large array of values, MongoDB can experience significant performance degradation. This is because the query effectively needs to scan a large portion of the collection to find matching documents, making it inefficient, especially without an appropriate index. This leads to slow query times and high resource consumption on the MongoDB server.
77

8-
## Full Code of Fixing Step by Step
8+
## Code Example & Fixing Steps
99

10-
Let's illustrate this with an example. Suppose we have a collection named `products` with a field `category` containing an array of categories:
10+
Let's assume we have a collection named `products` with documents like this:
1111

12-
```javascript
13-
// Sample document in 'products' collection
14-
{
15-
"_id": ObjectId("653a7f5e6b55808c7a984750"),
16-
"name": "Product A",
17-
"category": ["Electronics", "Gadgets", "Technology"]
18-
}
12+
```json
13+
{ "_id" : ObjectId("650b72764d5a3a468b46f0d4"), "category": "electronics", "name": "Laptop", "tags": ["laptop", "computer", "electronics"] }
14+
{ "_id" : ObjectId("650b728a4d5a3a468b46f0d5"), "category": "clothing", "name": "Shirt", "tags": ["shirt", "clothing", "fashion"] }
15+
{ "_id" : ObjectId("650b729e4d5a3a468b46f0d6"), "category": "electronics", "name": "Phone", "tags": ["phone", "mobile", "electronics"] }
1916
```
2017

21-
**Inefficient Query using $in:**
22-
23-
Imagine needing to find all products belonging to any of 1000 categories stored in an array called `categoriesToFind`:
18+
And we want to find products with tags within a large array:
2419

2520
```javascript
26-
db.products.find({ category: { $in: categoriesToFind } })
21+
// Inefficient query
22+
db.products.find({ tags: { $in: ["laptop", "computer", "electronics", "shirt", "clothing", "fashion", "phone", "mobile", ... (many more tags)] } });
2723
```
2824

29-
This query, if `categoriesToFind` is large, would be highly inefficient.
25+
This query will be slow with a large `$in` array.
3026

27+
**Fixing the problem:**
3128

32-
**Fixing the Problem:**
29+
1. **Create an Index:** The most effective solution is to create an index on the `tags` field. However, simply indexing `tags` isn't ideal for this use-case due to the nature of the `$in` query. Using a compound index won't help. A better approach is to restructure the data.
3330

34-
The best solution depends on the context, but here are a few strategies to improve performance:
31+
2. **Data Restructuring:** Instead of storing tags as an array, consider creating separate collections for products and tags with a many-to-many relationship. This involves creating a new collection, say `productTags`, that links products to tags:
3532

36-
**1. Using $or (for smaller arrays):** If the `categoriesToFind` array is relatively small (e.g., less than 100 elements), using the `$or` operator can sometimes be more efficient:
3733

34+
```json
35+
// products collection (simplified)
36+
{ "_id" : ObjectId("650b72764d5a3a468b46f0d4"), "category": "electronics", "name": "Laptop" }
37+
{ "_id" : ObjectId("650b728a4d5a3a468b46f0d5"), "category": "clothing", "name": "Shirt" }
3838

39-
```javascript
40-
const orQuery = categoriesToFind.map(category => ({ category: category }));
41-
db.products.find({ $or: orQuery });
39+
// productTags collection
40+
{ "product_id": ObjectId("650b72764d5a3a468b46f0d4"), "tag": "laptop" }
41+
{ "product_id": ObjectId("650b72764d5a3a468b46f0d4"), "tag": "computer" }
42+
{ "product_id": ObjectId("650b72764d5a3a468b46f0d4"), "tag": "electronics" }
43+
{ "product_id": ObjectId("650b728a4d5a3a468b46f0d5"), "tag": "shirt" }
44+
// ...and so on
4245
```
4346

44-
This creates multiple conditions, one for each category, which can be more efficient than a single `$in` query for small arrays.
45-
46-
47-
**2. Restructuring Data (Recommended):** The ideal solution is often to restructure the data to avoid needing the `$in` operator with large arrays. Instead of storing an array of categories in each document, create a separate collection or embed a reference field to a more appropriate structure.
47+
3. **Efficient Query:** Now, you can query efficiently using `$in` on the `tag` field within the `productTags` collection and then use aggregation to get the products.
4848

49-
**Example: Restructuring with embedded documents:**
5049
```javascript
51-
// New collection structure
52-
{
53-
"_id": ObjectId("653a7f5e6b55808c7a984751"),
54-
"name": "Product B",
55-
"categoryDetails": [
56-
{ "categoryId": 1, "categoryName": "Electronics" },
57-
{ "categoryId": 2, "categoryName": "Gadgets" }
58-
]
59-
}
60-
61-
// Querying using a specific categoryId:
62-
db.products.find({ "categoryDetails.categoryId": 1});
63-
64-
```
65-
This allows for efficient queries using indexes on `categoryDetails.categoryId`.
66-
67-
68-
**3. Creating a Compound Index (If Restructuring isn't feasible):**
69-
If restructuring isn't immediately possible, create a compound index on `category` to improve query performance.
70-
71-
```javascript
72-
db.products.createIndex( { "category": 1 } ); //Consider adding other fields for better selectivity.
73-
```
74-
This allows MongoDB to efficiently use the index for lookups but doesn't eliminate the problem entirely for very large arrays.
75-
76-
**4. Aggregation Framework with $lookup:** This approach can be more efficient when dealing with multiple collections and potentially large amounts of data.
77-
78-
```javascript
79-
db.categories.aggregate([
80-
{ $match: { _id: { $in: categoriesToFind } } },
81-
{
82-
$lookup: {
83-
from: "products",
84-
localField: "_id",
85-
foreignField: "categoryId",
86-
as: "products"
87-
}
88-
},
89-
{ $unwind: "$products" },
90-
{ $project: { _id: 0, products: 1 } }
50+
db.productTags.aggregate([
51+
{ $match: { tag: { $in: ["laptop", "computer", "electronics", "shirt", "clothing", "fashion", "phone", "mobile", ... ] } } },
52+
{ $group: { _id: "$product_id", tags: { $push: "$tag" } } },
53+
{ $lookup: {
54+
from: "products",
55+
localField: "_id",
56+
foreignField: "_id",
57+
as: "product"
58+
} },
59+
{ $unwind: "$product"},
60+
{ $project: { _id: "$product._id", name: "$product.name", category: "$product.category", tags: 1, _id:0} }
9161
])
62+
9263
```
9364

9465

9566
## Explanation
9667

97-
The `$in` operator's inefficiency with large arrays stems from its execution plan. MongoDB needs to scan the index (if one exists) or collection multiple times for each element in the `$in` array. This leads to increased I/O operations and significantly longer query times. Restructuring the data to eliminate the need for a large `$in` query is almost always the preferred solution for performance optimization. Using `$or` or a compound index can provide minor improvement but doesn't fundamentally address the underlying performance issue as efficiently as data restructuring.
98-
99-
68+
The original `$in` query against an array field forces a collection scan because an index can't efficiently utilize the array structure for such searches. By restructuring the data and creating a new collection with a more suitable schema, we can leverage indexes and utilize efficient queries, significantly improving performance, especially when dealing with a large number of tags and products. The aggregate query filters for relevant tags in `productTags` and then joins the data back to the `products` collection to retrieve the product information. This avoids the costly collection scan.
10069

10170
## External References
10271

103-
* [MongoDB Documentation on `$in` operator](https://www.mongodb.com/docs/manual/reference/operator/query/in/)
104-
* [MongoDB Documentation on Indexes](https://www.mongodb.com/docs/manual/indexes/)
105-
* [MongoDB Performance Tuning Guide](https://www.mongodb.com/docs/manual/administration/performance/)
72+
* [MongoDB Indexing Documentation](https://www.mongodb.com/docs/manual/indexes/)
73+
* [MongoDB Aggregation Framework](https://www.mongodb.com/docs/manual/aggregation/)
74+
* [Optimizing MongoDB Queries](https://www.mongodb.com/blog/post/optimizing-mongodb-queries-for-performance)
75+
10676

10777
Copyrights (c) OpenRockets Open-source Network. Free to use, copy, share, edit or publish.
10878

0 commit comments

Comments
 (0)