find 方法详细文档
📑 目录
概述
find 是 monSQLize 提供的基础查询方法,用于从 MongoDB 集合中查询多条文档记录。支持查询条件、排序、分页、投影、流式处理和缓存等功能。
✨ ObjectId 自动转换(v1.3.0+)
从 v1.3.0 版本开始,find 方法支持 ObjectId 字符串自动转换。当查询条件中包含 ObjectId 字符串时,会自动转换为 MongoDB 的 ObjectId 对象,无需手动调用 new ObjectId()。
了解更多: 详见 ObjectId 自动转换文档
调用方式
monSQLize 提供两种查询方式,功能完全等价:
方式 1: 链式调用(推荐)
支持的链式方法:
.limit(n)- 限制返回数量.skip(n)- 跳过文档数.sort(spec)- 排序规则.project(spec)- 字段投影.hint(spec)- 索引提示.collation(spec)- 排序规则.comment(str)- 查询注释.maxTimeMS(ms)- 超时时间.batchSize(n)- 批处理大小.explain(v)- 执行计划.stream()- 流式返回.toArray()- 显式转换为数组
📚 详细文档: 查看 链式调用完整 API 文档
方式 2: options 参数(传统方式,完全兼容)
两种方式完全等价,可以根据个人偏好和场景选择使用。
方法签名
参数说明:
query(Object): MongoDB 查询条件,如{ status: 'active', age: { $gt: 18 } }options(Object): 查询选项配置(仅 options 参数方式需要)
参数说明
query 参数
MongoDB 标准查询条件对象,支持所有 MongoDB 查询操作符。
options 对象属性
图例说明:
- ✅ MongoDB 原生: 该参数/方法是 MongoDB 官方支持的标准功能
- 🔧 monSQLize 扩展: monSQLize 独有的扩展功能,提供额外的便利性
MongoDB 参考文档:
comment 配置
查询注释用于在 MongoDB 日志中标识查询来源,便于生产环境的运维监控和性能分析:
命名建议:
使用场景:
- 生产环境监控:在 MongoDB 日志中识别查询来源
- 慢查询诊断:快速定位慢查询的业务场景
- 分布式追踪:结合 traceId 实现完整链路追踪
- 性能优化:A/B 测试不同查询策略的性能差异
- 审计与合规:记录查询发起者和业务场景
最佳实践:
- ✅ 使用统一的命名格式:"服务名:操作:标识符"
- ✅ 包含关键信息(用户ID、会话ID、traceId)
- ✅ 避免包含敏感数据(密码、身份证号等)
- ✅ 保持简洁(建议 <100 字符)
- ✅ 在生产环境启用 MongoDB 慢查询日志(slowOpThresholdMs)
MongoDB 日志示例:
参考文档:
projection 配置
投影配置用于指定查询结果中包含或排除的字段,支持两种格式:
对象格式:
数组格式:
注意:
- MongoDB 不允许混合使用包含(1)和排除(0),除了
_id字段 - 数组格式会自动转换为包含模式
_id字段默认总是包含,除非显式排除:{ _id: 0 }
sort 配置
排序配置指定结果的排序方式:
性能建议:
- 对于大数据集,确保排序字段上有索引
- 避免对未索引的字段进行排序
- 使用复合索引可以优化多字段排序
hint 配置
强制 MongoDB 使用指定的索引:
使用场景:
- MongoDB 查询优化器选择了错误的索引
- 需要强制使用特定索引以保证性能
- 测试不同索引的性能差异
collation 配置
指定字符串比较和排序的规则:
常见场景:
- 需要不区分大小写的查询和排序
- 多语言环境下的正确排序
- 数字字符串的自然排序
返回值
普通模式返回数组
默认情况下,find 方法返回一个 Promise,resolve 为文档数组:
返回值类型:Promise<Array<Object>>
流式模式返回流对象
当 stream: true 时,返回一个 MongoDB Cursor Stream 对象:
返回值类型:ReadableStream
explain 模式返回执行计划
当 explain 为 true 或指定级别时,返回查询执行计划:
返回值类型:Promise<Object>
使用模式
1. 基础查询
最简单的查询方式,返回所有匹配的文档:
适用场景:
- 数据量较小的集合
- 需要一次性获取所有结果
- 结果数量可控(建议设置 limit)
2. 分页查询(skip + limit)
使用 skip 和 limit 实现传统的分页:
性能注意:
- skip 在大数据集上性能差(需要遍历跳过的文档)
- 不推荐 skip 超过 10,000
- 对于高性能分页,推荐使用
findPage方法
3. 流式处理
流式处理大数据集,避免内存溢出:
优势:
- 内存占用恒定(只保存当前批次)
- 适合处理百万级数据
- 支持管道(pipe)操作
注意:
- 流式处理不支持缓存
- 建议设置合适的 batchSize(默认 1000)
4. 复杂查询条件
使用 MongoDB 查询操作符构建复杂查询:
5. 使用索引优化
通过 hint 强制使用索引,explain 查看执行计划:
6. 缓存查询结果
对于频繁查询且变化不大的数据,使用缓存提升性能:
缓存说明:
- 缓存键基于查询条件、排序、投影等参数自动生成
- 相同查询条件会复用缓存
- 缓存存储在实例级别(进程内存)
- 适合读多写少的场景
性能优化建议
1. 合理使用 limit
始终为查询设置合理的 limit,避免返回过多数据:
2. 只查询需要的字段
使用 projection 减少数据传输:
3. 为排序字段建立索引
4. 避免大 skip
5. 大数据集使用流式处理
6. 设置查询超时
防止慢查询阻塞系统:
错误处理
与 findPage 的区别
选择建议:
- 简单的一次性查询:使用
find - 需要分页的列表:使用
findPage - 大数据集处理:两者都支持 stream
- 需要总数统计:使用
findPage
参考资料
常见问题 FAQ
Q1: find 和 findPage 应该如何选择?
A: 根据使用场景选择:
-
使用 find:
- 一次性获取少量数据(< 100 条)
- 不需要分页功能
- 简单的数据导出或统计
- 已知数据量很小
-
使用 findPage:
- 需要分页展示列表
- 数据量较大(> 1000 条)
- 需要游标分页功能
- 需要获取总数统计
Q2: 为什么不推荐大量使用 skip?
A: skip 的性能问题:
- MongoDB 必须遍历所有被跳过的文档
- skip(10000) 需要扫描 10000 个文档
- 在大数据集上性能呈线性下降
- 推荐使用 findPage 的游标分页替代
Q3: 如何优化 find 查询性能?
A: 性能优化清单:
- ✅ 为查询字段和排序字段创建索引
- ✅ 使用 projection 只查询需要的字段
- ✅ 设置合理的 limit 限制
- ✅ 使用 explain 分析查询计划
- ✅ 对频繁查询启用缓存
- ✅ 大数据集使用流式处理
- ✅ 设置 maxTimeMS 防止慢查询
Q4: 流式查询什么时候使用?
A: 适合使用流式查询的场景:
- 数据量超过 10 万条
- 需要逐条处理数据
- 内存有限制
- 数据导出或 ETL 操作
- 实时数据处理
Q5: 缓存什么时候失效?
A: 缓存失效机制:
- 达到 TTL 时间自动失效
- 调用
collection.invalidate()手动失效 - 进程重启后缓存清空
- 缓存键基于查询参数生成,参数变化则缓存失效
Q6: 如何处理大数据量的排序?
A: 大数据排序优化:
Q7: 如何调试慢查询?
A: 慢查询调试步骤:
最佳实践
1. 始终设置 limit
2. 使用投影减少数据传输
3. 复合排序确保稳定性
4. 合理使用缓存
5. 处理异常情况
6. 批量处理大数据
版本历史
- v1.0.0 (2025-01-12): 初始版本,完整的 find 方法文档