Amazon DocumentDB 高级查询 #
一、复杂条件查询 #
1.1 嵌套逻辑组合 #
javascript
// 复杂的AND/OR组合
db.users.find({
$and: [
{
$or: [
{ role: "admin" },
{ role: "superuser" }
]
},
{
$or: [
{ status: "active" },
{ lastLogin: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) } }
]
}
]
})
1.2 条件表达式 #
javascript
// 使用$expr进行字段间比较
db.products.find({
$expr: {
$gt: ["$price", "$cost"]
}
})
// 字段间运算
db.orders.find({
$expr: {
$gt: [
{ $multiply: ["$quantity", "$price"] },
1000
]
}
})
1.3 条件分支 #
javascript
// 使用$cond进行条件判断
db.sales.aggregate([
{
$project: {
name: 1,
amount: 1,
status: {
$cond: {
if: { $gte: ["$amount", 1000] },
then: "high",
else: "normal"
}
}
}
}
])
二、数组高级操作 #
2.1 数组元素查询 #
javascript
// 查询数组中特定条件的元素
db.users.find({
scores: { $elemMatch: { $gt: 80, $lt: 90 } }
})
// 嵌套对象数组查询
db.users.find({
education: {
$elemMatch: {
school: "清华大学",
degree: "本科"
}
}
})
// 多条件数组查询
db.products.find({
variants: {
$elemMatch: {
color: "red",
size: "L",
stock: { $gt: 0 }
}
}
})
2.2 数组长度查询 #
javascript
// 查询数组长度
db.users.find({ tags: { $size: 3 } })
// 查询数组长度大于某值(需要聚合)
db.users.aggregate([
{
$addFields: {
tagsCount: { $size: "$tags" }
}
},
{
$match: {
tagsCount: { $gt: 3 }
}
}
])
2.3 数组操作符 #
javascript
// $all - 包含所有元素
db.articles.find({
tags: { $all: ["mongodb", "database", "nosql"] }
})
// $elemMatch - 元素匹配
db.students.find({
grades: {
$elemMatch: {
subject: "数学",
score: { $gte: 90 }
}
}
})
// 数组索引查询
db.users.find({ "tags.0": "编程" }) // 第一个元素
db.users.find({ "tags.1": "阅读" }) // 第二个元素
2.4 数组更新后查询 #
javascript
// 使用$定位操作符
db.users.find(
{ "grades.subject": "数学" },
{ "grades.$": 1 }
)
// 使用$elemMatch投影
db.students.find(
{ name: "张三" },
{
grades: {
$elemMatch: { score: { $gte: 90 } }
}
}
)
三、正则表达式高级用法 #
3.1 复杂正则匹配 #
javascript
// 多条件正则
db.users.find({
$or: [
{ email: { $regex: /^[a-z]+@example\.com$/i } },
{ phone: { $regex: /^1[3-9]\d{9}$/ } }
]
})
// 正则组合
db.products.find({
name: { $regex: /^(iPhone|iPad|Mac)/ }
})
// 排除模式
db.users.find({
email: { $not: { $regex: /test@/ } }
})
3.2 正则选项 #
javascript
// 不区分大小写
db.users.find({
name: { $regex: /zhang/i }
})
// 多行模式
db.articles.find({
content: { $regex: /^Title/m }
})
// 使用$options
db.users.find({
email: {
$regex: "^[a-z]+@example\\.com$",
$options: "i"
}
})
3.3 性能考虑 #
text
正则查询性能:
├── 前缀匹配可以使用索引(/^prefix/)
├── 其他正则无法使用索引
├── 大数据量正则查询可能很慢
└── 考虑使用文本索引替代
四、地理空间查询 #
4.1 地理空间索引 #
javascript
// 创建2dsphere索引
db.locations.createIndex({ location: "2dsphere" })
// 创建2d索引
db.places.createIndex({ coords: "2d" })
4.2 附近查询 #
javascript
// 查找附近的点
db.locations.find({
location: {
$near: {
$geometry: {
type: "Point",
coordinates: [116.4074, 39.9042] // 经度, 纬度
},
$maxDistance: 1000, // 最大距离(米)
$minDistance: 0
}
}
})
// 使用$nearSphere(球面距离)
db.locations.find({
location: {
$nearSphere: {
$geometry: {
type: "Point",
coordinates: [116.4074, 39.9042]
},
$maxDistance: 5000
}
}
})
4.3 范围查询 #
javascript
// 圆形范围
db.locations.find({
location: {
$geoWithin: {
$centerSphere: [
[116.4074, 39.9042], // 圆心
5 / 6371 // 半径(弧度)
]
}
}
})
// 多边形范围
db.locations.find({
location: {
$geoWithin: {
$geometry: {
type: "Polygon",
coordinates: [[
[116.0, 39.0],
[117.0, 39.0],
[117.0, 40.0],
[116.0, 40.0],
[116.0, 39.0]
]]
}
}
}
})
4.4 GeoJSON类型 #
javascript
// Point
{
location: {
type: "Point",
coordinates: [116.4074, 39.9042]
}
}
// LineString
{
route: {
type: "LineString",
coordinates: [
[116.0, 39.0],
[117.0, 40.0]
]
}
}
// Polygon
{
area: {
type: "Polygon",
coordinates: [[
[116.0, 39.0],
[117.0, 39.0],
[117.0, 40.0],
[116.0, 40.0],
[116.0, 39.0]
]]
}
}
五、文本搜索 #
5.1 创建文本索引 #
javascript
// 创建文本索引
db.articles.createIndex({ title: "text", content: "text" })
// 创建多语言文本索引
db.articles.createIndex(
{ content: "text" },
{ default_language: "chinese" }
)
// 指定权重
db.articles.createIndex(
{ title: "text", content: "text" },
{ weights: { title: 10, content: 5 } }
)
5.2 文本搜索 #
javascript
// 基本文本搜索
db.articles.find({ $text: { $search: "数据库" } })
// 多词搜索(OR关系)
db.articles.find({ $text: { $search: "数据库 MongoDB" } })
// 短语搜索
db.articles.find({ $text: { $search: "\"文档数据库\"" } })
// 排除词
db.articles.find({ $text: { $search: "数据库 -MySQL" } })
5.3 文本搜索评分 #
javascript
// 获取搜索相关性评分
db.articles.find(
{ $text: { $search: "数据库" } },
{ score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })
六、$lookup关联查询 #
6.1 基本关联 #
javascript
// 左连接
db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}
}
])
// 输出
{
"_id": ObjectId("..."),
"orderNo": "ORD001",
"userId": ObjectId("..."),
"user": [
{
"_id": ObjectId("..."),
"name": "张三",
"email": "zhangsan@example.com"
}
]
}
6.2 多条件关联 #
javascript
// 复杂关联条件
db.orders.aggregate([
{
$lookup: {
from: "products",
let: { productId: "$productId", qty: "$quantity" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ["$_id", "$$productId"] },
{ $gte: ["$stock", "$$qty"] }
]
}
}
}
],
as: "availableProducts"
}
}
])
6.3 关联后处理 #
javascript
// 展开数组并选择字段
db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}
},
{
$unwind: "$user"
},
{
$project: {
orderNo: 1,
amount: 1,
userName: "$user.name",
userEmail: "$user.email"
}
}
])
七、$graphLookup图查询 #
7.1 递归关联 #
javascript
// 组织架构递归查询
db.employees.aggregate([
{
$graphLookup: {
from: "employees",
startWith: "$managerId",
connectFromField: "managerId",
connectToField: "_id",
as: "managers",
depthField: "level"
}
}
])
7.2 限制深度 #
javascript
// 限制递归深度
db.categories.aggregate([
{
$graphLookup: {
from: "categories",
startWith: "$parentId",
connectFromField: "parentId",
connectToField: "_id",
maxDepth: 3,
as: "ancestors"
}
}
])
八、查询优化技巧 #
8.1 索引覆盖查询 #
javascript
// 创建复合索引
db.users.createIndex({ email: 1, name: 1 })
// 索引覆盖查询(只返回索引字段)
db.users.find(
{ email: "test@example.com" },
{ _id: 0, email: 1, name: 1 }
)
8.2 查询提示 #
javascript
// 强制使用指定索引
db.users.find({ email: "test@example.com" }).hint({ email: 1 })
// 禁用索引
db.users.find({ email: "test@example.com" }).hint({ $natural: 1 })
8.3 批量大小优化 #
javascript
// 设置批量大小
db.users.find({}).batchSize(100)
// 流式处理大数据
const cursor = db.users.find({}).batchSize(100);
while (cursor.hasNext()) {
const doc = cursor.next();
// 处理文档
}
8.4 查询超时设置 #
javascript
// 设置最大执行时间
db.users.find({}).maxTimeMS(5000)
// 聚合查询超时
db.users.aggregate([...], { maxTimeMS: 10000 })
九、实际应用示例 #
9.1 多条件搜索 #
javascript
function advancedSearch(options) {
const pipeline = [];
const match = {};
// 关键词搜索
if (options.keyword) {
match.$text = { $search: options.keyword };
}
// 分类筛选
if (options.category) {
match.category = options.category;
}
// 价格范围
if (options.minPrice || options.maxPrice) {
match.price = {};
if (options.minPrice) match.price.$gte = options.minPrice;
if (options.maxPrice) match.price.$lte = options.maxPrice;
}
// 标签筛选
if (options.tags && options.tags.length > 0) {
match.tags = { $all: options.tags };
}
// 评分筛选
if (options.minRating) {
match.rating = { $gte: options.minRating };
}
pipeline.push({ $match: match });
// 排序
if (options.sortBy) {
const sort = {};
sort[options.sortBy] = options.sortOrder === 'desc' ? -1 : 1;
pipeline.push({ $sort: sort });
}
// 分页
pipeline.push({ $skip: (options.page - 1) * options.pageSize });
pipeline.push({ $limit: options.pageSize });
return db.products.aggregate(pipeline);
}
9.2 统计分析查询 #
javascript
// 销售统计分析
db.orders.aggregate([
{
$match: {
createdAt: {
$gte: new Date("2024-01-01"),
$lt: new Date("2024-02-01")
}
}
},
{
$group: {
_id: {
year: { $year: "$createdAt" },
month: { $month: "$createdAt" },
day: { $dayOfMonth: "$createdAt" }
},
totalSales: { $sum: "$amount" },
orderCount: { $sum: 1 },
avgOrderValue: { $avg: "$amount" }
}
},
{
$sort: { "_id.year": 1, "_id.month": 1, "_id.day": 1 }
}
])
十、总结 #
10.1 高级查询技术 #
| 技术 | 用途 |
|---|---|
| $expr | 字段间比较 |
| $elemMatch | 数组元素匹配 |
| $regex | 正则匹配 |
| $near | 地理位置查询 |
| $text | 文本搜索 |
| $lookup | 关联查询 |
| $graphLookup | 递归关联 |
10.2 最佳实践 #
text
高级查询最佳实践:
├── 合理使用索引
├── 避免全表扫描
├── 使用explain分析性能
├── 设置查询超时
├── 分页处理大数据
└── 监控慢查询
下一步,让我们学习聚合管道!
最后更新:2026-03-27