Attribute pattern for variable fields in MongoDB - Time & Space Complexity
When working with variable fields in MongoDB documents, queries often use attribute patterns to find matching fields.
We want to understand how the time to run these queries changes as the data grows.
Analyze the time complexity of the following MongoDB query using attribute pattern matching.
db.collection.find({
"attributes.color": { $exists: true },
"attributes.size": { $exists: true }
})
.limit(100)
This query finds documents where the "attributes" object has both "color" and "size" fields.
Look for repeated checks or scans in the query process.
- Primary operation: Scanning each document to check if the "attributes" object contains the specified fields.
- How many times: Once per document in the collection until 100 matches are found or all documents are checked.
As the number of documents grows, the query must check more documents to find matches.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 10 document checks |
| 100 | Up to 100 document checks |
| 1000 | Up to 1000 document checks |
Pattern observation: The number of checks grows roughly in direct proportion to the number of documents.
Time Complexity: O(n)
This means the time to run the query grows linearly with the number of documents in the collection.
[X] Wrong: "The query will always be fast because it only looks for two fields."
[OK] Correct: Even though the query looks for two fields, MongoDB must check each document's attributes, so the time depends on how many documents there are.
Understanding how queries with variable fields scale helps you explain performance and indexing strategies clearly in real-world situations.
What if we added an index on "attributes.color" and "attributes.size"? How would the time complexity change?
Practice
Solution
Step 1: Understand pattern matching in MongoDB
MongoDB uses $regex to match string patterns inside field values.Step 2: Identify the operator for text pattern search
$regex is the operator designed for regular expression matching in queries.Final Answer:
$regex -> Option BQuick Check:
Pattern matching = $regex [OK]
- Confusing $regex with $match which filters documents
- Using $group which aggregates data, not filters by pattern
- Using $project which reshapes documents, not filters
Solution
Step 1: Understand field-to-array conversion
$objectToArray converts document fields into an array of {k, v} pairs.Step 2: Identify the correct stage for this conversion
$objectToArray is the aggregation operator that does this transformation.Final Answer:
$objectToArray -> Option AQuick Check:
Field to array = $objectToArray [OK]
- Using $filter which filters arrays but doesn't convert fields
- Confusing $arrayToObject which does the reverse conversion
- Using $match which filters documents, not fields
{
$project: {
filteredFields: {
$filter: {
input: { $objectToArray: "$ROOT" },
as: "field",
cond: { $regexMatch: { input: "$$field.k", regex: /^a/ } }
}
}
}
}Solution
Step 1: Convert document fields to array
$objectToArray converts {"a1":5,"b2":10,"c3":15} to [{k:"a1",v:5},{k:"b2",v:10},{k:"c3",v:15}].Step 2: Filter keys starting with 'a'
$filter with regex /^a/ keeps only fields where key starts with 'a', so only {k:"a1",v:5} remains.Final Answer:
{"filteredFields": [{"k": "a1", "v": 5}]} -> Option AQuick Check:
Filter keys /^a/ = only "a1" field [OK]
- Forgetting to convert fields to array before filtering
- Using wrong regex pattern or syntax
- Expecting all fields instead of filtered ones
{
$project: {
scores: {
$filter: {
input: { $objectToArray: "$ROOT" },
as: "field",
cond: { $regex: "score", input: "$$field.k" }
}
}
}
}Solution
Step 1: Check $regex usage inside $filter cond
$regex is a query operator, but inside aggregation expressions, $regexMatch must be used for regex matching.Step 2: Identify correct regex function for aggregation
Use $regexMatch with 'input' and 'regex' keys; $regex alone is invalid here.Final Answer:
Using $regex instead of $regexMatch inside $filter condition -> Option CQuick Check:
Aggregation regex = $regexMatch, not $regex [OK]
- Swapping input and regex keys in $regexMatch
- Trying to use $regex query operator inside aggregation
- Assuming $objectToArray can't be used on $ROOT
Solution
Step 1: Convert document fields to array for filtering
Use $objectToArray on "$ROOT" to get array of key-value pairs.Step 2: Filter keys starting with "score_" using $filter and $regexMatch
Apply $filter with condition $regexMatch on keys matching /^score_/.Step 3: Convert filtered array back to object
Use $arrayToObject to convert filtered array back to an object with only score fields.Final Answer:
{ $project: { scores: { $arrayToObject: { $filter: { input: { $objectToArray: "$ROOT" }, as: "f", cond: { $regexMatch: { input: "$$f.k", regex: /^score_/ } } } } } } } -> Option DQuick Check:
Filter keys + convert back = { $project: { scores: { $arrayToObject: { $filter: { input: { $objectToArray: "$ROOT" }, as: "f", cond: { $regexMatch: { input: "$$f.k", regex: /^score_/ } } } } } } } [OK]
- Trying to filter directly on $ROOT without conversion
- Using $match instead of $project for field transformation
- Not converting filtered array back to object with $arrayToObject
Ready to prove it?
Pass the test and this pattern moves unknown
