비교 연산자: $eq, $gt, $lt, $in
비교 연산자를 사용하여 숫자 범위, 정확히 일치하는 값, 목록에 포함된 항목을 기준으로 문서를 필터링합니다.
비교 연산자: $eq, $gt, $lt, $in은(는) CoddyKit의 무료 MongoDB Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 MongoDB Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. MongoDB Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
Beyond Equality Filters
Simple equality filters like { status: 'active' } are useful, but real queries need more nuance. MongoDB provides a rich set of query operators prefixed with $ that express conditions beyond simple equality. These operators let you filter by numeric ranges, membership in a list, value presence, and pattern matching.
Comparison operators are the most commonly used category. They work on any comparable BSON type: numbers, strings (lexicographic comparison), dates, and even ObjectIds (chronological order, since ObjectIds encode timestamps).
$eq: Explicit Equality
The $eq operator explicitly tests for equality: { age: { $eq: 30 } }. In most cases, the shorthand { age: 30 } is identical and preferred for readability—$eq is mainly useful when the operator is needed inside another expression like $expr.
One difference: $eq inside aggregation pipeline expressions is required when comparing two field values (e.g., { $eq: ['$price', '$salePrice'] }). In regular find filters, stick to the shorthand equality syntax unless a specific context requires the operator form.
// These two queries are equivalent in find()
db.users.find({ age: 30 });
db.users.find({ age: { $eq: 30 } });
// $eq is useful inside $expr for field-to-field comparison:
db.products.find({
$expr: { $eq: ['$price', '$salePrice'] }
});
// Returns products where price equals salePrice$gt and $gte: Greater Than
$gt (greater than) and $gte (greater than or equal) filter documents where a field's value exceeds a threshold. These work on numbers, dates, strings (lexicographic order), and ObjectIds.
Date comparisons are particularly powerful: { createdAt: { $gte: new Date('2024-01-01') } } finds all documents created since January 1, 2024. This query can use an index on createdAt for O(log n) performance, making date-range queries extremely efficient even on large collections.
// Numeric range
db.products.find({ price: { $gt: 100 } });
// price > 100
db.employees.find({ salary: { $gte: 50000 } });
// salary >= 50000
// Date comparison
db.orders.find({
createdAt: { $gte: new Date('2024-01-01') }
});
// Orders placed since Jan 1, 2024
// String comparison (lexicographic)
db.users.find({ lastName: { $gte: 'M' } });
// Last names starting with M-Z$lt and $lte: Less Than
$lt (less than) and $lte (less than or equal) are the complements of $gt/$gte. Combine both operators on the same field to create a range query—MongoDB applies both conditions to the same field, equivalent to SQL's BETWEEN.
Range queries on indexed fields are very efficient because MongoDB can seek to the lower bound in the index and scan forward to the upper bound, touching only the relevant entries. This is one of the primary reasons to index fields you frequently filter by range.
// Price < 50
db.products.find({ price: { $lt: 50 } });
// Age <= 17 (minors)
db.users.find({ age: { $lte: 17 } });
// Range query: price between 20 and 100 (inclusive)
db.products.find({ price: { $gte: 20, $lte: 100 } });
// Equivalent SQL: WHERE price BETWEEN 20 AND 100
// Date range: orders placed last week
const weekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
db.orders.find({ createdAt: { $gte: weekAgo, $lte: new Date() } });$ne: Not Equal
$ne (not equal) matches documents where a field's value is not equal to the specified value. It also matches documents where the field does not exist at all—because a missing field is implicitly not equal to any value.
Be cautious with $ne on large, unindexed collections: MongoDB typically cannot use an index to satisfy a negation efficiently and may fall back to a collection scan. For heavily filtered queries, prefer positive conditions ($eq, $in) over negative ones when possible.
// Find orders that are not cancelled
db.orders.find({ status: { $ne: 'cancelled' } });
// Find users who have NOT set a display name
// ($ne also matches missing field)
db.users.find({ displayName: { $ne: null } });
// Caution: $ne on non-indexed field scans full collection
// Index the field if used frequently:
db.orders.createIndex({ status: 1 });
db.orders.find({ status: { $ne: 'cancelled' } }); // Uses index$in: Match Any Value in a List
$in matches documents where a field's value equals any value in a provided array. It is the MongoDB equivalent of SQL's IN clause. This is far more concise than writing multiple $or conditions for the same field.
On an indexed field, $in is implemented as multiple point lookups in the index tree—one per value in the array—which is very efficient. For large lists (hundreds of values), performance degrades, but for typical use cases (5-20 values), $in is a great choice.
// Find products in specific categories
db.products.find({
category: { $in: ['Electronics', 'Computers', 'Peripherals'] }
});
// Equivalent SQL: WHERE category IN ('Electronics', 'Computers', 'Peripherals')
// Find orders with specific statuses
db.orders.find({
status: { $in: ['pending', 'processing', 'shipped'] }
});
// $in on array field: matches if arrays share any element
db.products.find({
tags: { $in: ['sale', 'clearance'] }
}); // Products with 'sale' OR 'clearance' in their tags array$nin: Not In a List
$nin (not in) is the negation of $in—it matches documents where the field's value is not in the provided array (and also matches documents where the field is absent). Like $ne, it can be less efficient than $in because it often requires scanning documents.
A practical use case: excluding a known set of IDs. If a user has blocked certain other users, you might exclude their content: { authorId: { $nin: blockedUserIds } }. Keep the exclusion list small for best performance.
// Exclude archived and deleted statuses
db.tickets.find({
status: { $nin: ['archived', 'deleted', 'spam'] }
});
// Exclude a user's own posts from their feed
const blockedIds = [ObjectId('...'), ObjectId('...')] ;
db.posts.find({
authorId: { $nin: blockedIds }
}).sort({ createdAt: -1 }).limit(20);Combining Comparison Operators
You can combine multiple comparison operators on the same field or different fields in a single query. When operators appear on the same field in one object, they act as an implicit AND—both conditions must be true. When they are on different fields, both conditions must also be true.
Build complex filters by thinking about each field independently and combining conditions. MongoDB evaluates all field conditions together, using indexes where available to minimize the documents examined.
// Products priced between $20-$100, in stock, created this year
const thisYear = new Date('2024-01-01');
db.products.find({
price: { $gte: 20, $lte: 100 }, // Range on price
stock: { $gt: 0 }, // In stock
category: { $in: ['Electronics', 'Home'] }, // Category filter
createdAt: { $gte: thisYear } // Created this year
}).sort({ price: 1 });Comparison Operators on Dates
Date comparisons are among the most common uses of comparison operators in real applications. MongoDB's Date BSON type stores dates as 64-bit milliseconds, so all comparison operators work naturally on date fields.
Common patterns include: finding records created in the last N days, filtering active subscriptions that expire after today, and range queries for reporting periods. Always construct Date objects in the query—never compare dates as strings, as lexicographic string comparison gives incorrect results for most date formats.
// Records created in the last 30 days
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
db.events.find({ createdAt: { $gte: thirtyDaysAgo } });
// Subscriptions that expire in the future (still active)
db.subscriptions.find({ expiresAt: { $gt: new Date() } });
// Orders placed on a specific day (date range for one day)
const startOfDay = new Date('2024-06-01T00:00:00Z');
const endOfDay = new Date('2024-06-01T23:59:59.999Z');
db.orders.find({ createdAt: { $gte: startOfDay, $lte: endOfDay } });Performance: Indexes and Comparison Queries
Comparison operators benefit enormously from indexes. An index on a numeric field turns an O(n) scan into O(log n + result size). Key points:
- Range queries (
$gt,$lt) can use a single-field index to navigate directly to the range start $inperforms multiple point lookups in the index—one per value- Negation operators (
$ne,$nin) often scan the index rather than using point lookups, so they are less efficient - Use
explain('executionStats')to verify your comparison queries use IXSCAN and not COLLSCAN
// Verify range query uses index
db.products.find({ price: { $gte: 20, $lte: 100 } })
.explain('executionStats');
// Look for: winningPlan.stage = 'IXSCAN'
// If COLLSCAN: add index with db.products.createIndex({ price: 1 })
// Create compound index for combined filter:
db.products.createIndex({ category: 1, price: 1 });
// Supports: { category: 'Electronics', price: { $gte: 50 } }Using Comparison Operators With Aggregation
Comparison operators appear in two contexts: as query operators in find() filters (with the syntax { field: { : value } }) and as expression operators in the aggregation pipeline and stages (with a different syntax: { : ['', value] }).
In , expression operators return a boolean or a computed value. For example, you can add a computed field isExpensive that is true when price exceeds 100: { : { isExpensive: { : ['', 100] } } }. The stage uses the same query syntax as find().
// Comparison in aggregation pipeline:
db.products.aggregate([
// uses same syntax as find()
{ : { price: { : 20, : 100 } } },
// uses expression operator syntax:
{
: {
isExpensive: { : ['', 80] }, // Returns boolean
discountedPrice: { : ['', 0.9] } // Computes value
}
}
]);Quick Check
Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.
Lesson Recap
In this lesson you learned: $gt/$gte/$lt/$lte create range conditions on numbers, dates, and strings, and work with indexes for O(log n) range scans, $in matches any value from a list and is significantly more readable and efficient than multiple $or equality conditions on the same field, and $ne/$nin are negation operators that match anything outside the given value/list but are less index-efficient than their positive counterparts. Next up we explore logical operators—$and, $or, $nor, and $not—to combine conditions across different fields.
자주 묻는 질문
“비교 연산자: $eq, $gt, $lt, $in” 강의는 무료인가요?
네 — “비교 연산자: $eq, $gt, $lt, $in” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 MongoDB Academy 강의 전체를 잠금 해제할 수 있습니다. MongoDB Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“비교 연산자: $eq, $gt, $lt, $in”에서 뭘 배우나요?
비교 연산자를 사용하여 숫자 범위, 정확히 일치하는 값, 목록에 포함된 항목을 기준으로 문서를 필터링합니다. 브라우저에서 직접 실행하는 실습 코드로 MongoDB Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
MongoDB Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 MongoDB Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“비교 연산자: $eq, $gt, $lt, $in” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 MongoDB Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 MongoDB Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 비교 연산자: $eq, $gt, $lt, $in
- 논리 연산자: $and, $or, $nor, $not
- 요소 연산자와 유형 검사
- 정규식 쿼리와 패턴 일치