Document queries (find, findOne)
Query Basics
MongoDB provides two core methods for document queries: find()
and findOne()
. find()
returns all documents that match the query conditions, while findOne()
returns only the first matching document. Both accept query conditions as parameters. If no parameters are provided, find()
returns all documents in the collection, and findOne()
returns the first document.
// Find all users
db.users.find()
// Find the first user
db.users.findOne()
// Find users aged 25
db.users.find({ age: 25 })
// Find the first user aged 25
db.users.findOne({ age: 25 })
Query Conditions
Query conditions are specified in JSON format and can include various comparison and logical operators. Basic query conditions use direct field-value matching:
// Exact match
db.products.find({ category: "electronics" })
// Using comparison operators
db.products.find({ price: { $gt: 100 } }) // Price greater than 100
Common comparison operators include:
$eq
: Equal to$ne
: Not equal to$gt
: Greater than$gte
: Greater than or equal to$lt
: Less than$lte
: Less than or equal to$in
: In an array$nin
: Not in an array
Logical Operators
MongoDB provides logical operators to combine multiple query conditions:
// AND operation (implicit)
db.users.find({ age: 25, status: "active" })
// AND operation (explicit)
db.users.find({ $and: [{ age: 25 }, { status: "active" }] })
// OR operation
db.users.find({ $or: [{ age: 25 }, { status: "active" }] })
// NOT operation
db.users.find({ age: { $not: { $gt: 30 } } })
Querying Nested Documents
For nested documents, dot notation can be used:
// Find users where address.city is "New York"
db.users.find({ "address.city": "New York" })
// Query elements in nested arrays
db.users.find({ "hobbies": "reading" })
// Use $elemMatch to query compound conditions in arrays
db.users.find({
scores: {
$elemMatch: {
type: "exam",
score: { $gt: 90 }
}
}
})
Projection (Field Selection)
The second parameter of find()
and findOne()
specifies which fields to return (projection):
// Return only name and email fields
db.users.find({}, { name: 1, email: 1 })
// Exclude _id field
db.users.find({}, { _id: 0, name: 1, email: 1 })
// Exclude status field
db.users.find({}, { status: 0 })
Querying Arrays
Several special operators are available for array queries:
// Exact match of the entire array
db.users.find({ tags: ["red", "blue"] })
// Match any element in the array
db.users.find({ tags: "red" })
// Use $all to match arrays containing all specified elements
db.users.find({ tags: { $all: ["red", "blue"] } })
// Use $size to match arrays of a specific length
db.users.find({ tags: { $size: 3 } })
Pagination and Sorting
Combining limit()
, skip()
, and sort()
enables paginated queries:
// First page, 10 items per page, sorted by creation time in descending order
db.users.find()
.sort({ createdAt: -1 })
.limit(10)
.skip(0)
// Second page
db.users.find()
.sort({ createdAt: -1 })
.limit(10)
.skip(10)
Performance Considerations
Query performance is influenced by several factors:
- Indexes: Ensure query fields have appropriate indexes.
- Projection: Return only necessary fields.
- Query selectivity: Highly selective queries (returning few documents) perform better.
- Avoid full collection scans: Use
explain()
to analyze query plans.
// Analyze a query
db.users.find({ age: 25 }).explain("executionStats")
Aggregation Queries
While find()
and findOne()
are suitable for simple queries, complex data processing can use the aggregation framework:
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 10 }
])
Text Search
MongoDB supports text indexes and search:
// Create a text index
db.articles.createIndex({ title: "text", content: "text" })
// Text search
db.articles.find({ $text: { $search: "mongodb tutorial" } })
Geospatial Queries
For documents containing geospatial data, special query operators are available:
// Find places within 1000 meters of a point
db.places.find({
location: {
$near: {
$geometry: {
type: "Point",
coordinates: [longitude, latitude]
},
$maxDistance: 1000
}
}
})
Query Optimization Tips
- Use covered queries (queries that only use fields in the index).
- Avoid
$where
(JavaScript expressions have poor performance). - Use
hint()
appropriately to force specific indexes. - Monitor slow query logs.
// Force a specific index
db.users.find({ age: 25 }).hint({ age: 1 })
Queries in Transactions
In MongoDB transactions, query behavior is similar to regular queries, but isolation levels must be considered:
session.startTransaction()
try {
const user = db.users.findOne({ _id: userId }, { session })
// Process logic
session.commitTransaction()
} catch (error) {
session.abortTransaction()
}
Bulk Query Operations
For large datasets, bulk query methods can improve efficiency:
// Bulk find multiple IDs
db.users.find({ _id: { $in: [id1, id2, id3] } })
// Use cursors to process large datasets
const cursor = db.users.find()
while (cursor.hasNext()) {
const doc = cursor.next()
// Process document
}
Queries and Replica Sets
In replica set environments, read preferences can be specified:
// Read from primary (default)
db.users.find().readPref("primary")
// Read from secondary
db.users.find().readPref("secondary")
// Read from the nearest node
db.users.find().readPref("nearest")
Queries and Sharded Clusters
In sharded clusters, queries are routed to the appropriate shards:
// When the query includes a shard key, it can be routed directly to a specific shard
db.orders.find({ customerId: "123" }) // Assuming customerId is the shard key
// Queries without a shard key are broadcast to all shards (poor performance)
db.orders.find({ status: "pending" })
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn