
在 firestore 中,通过文档 id 直接获取(collection.doc(id).get())与通过字段值查询(collection.where('id', '==', id).get())在理论性能上完全一致——二者均基于索引、均返回单文档时耗时无显著差异。实际开发中应优先选择语义清晰、可维护性更高的方式。
Firestore 的底层查询机制决定了其性能不取决于集合总文档量,而仅与结果集大小相关。当你使用 collection.doc(id).get() 时,Firestore 会直接定位到该文档的物理存储位置(类似哈希查找);而 collection.where('id', '==', id).get() 在存在单字段索引(默认为 id 字段自动创建)的前提下,同样能以 O(log n) 时间复杂度完成索引扫描——当结果恒为 1 条时,两者实际 I/O 和网络开销几乎相同。
✅ 推荐做法:始终优先使用文档 ID 直接获取
// ✅ 推荐:语义明确、代码简洁、无需处理数组
const docRef = db.collection('users').doc('user_123');
docRef.get().then((snap) => {
if (snap.exists) {
console.log('Data:', snap.data());
}
});
// ❌ 不推荐:冗余查询、额外开销、需手动解包
db.collection('users')
.where('id', '==', 'user_123')
.get()
.then((querySnap) => {
const doc = querySnap.docs[0]; // 假设存在且唯一,但需防御性检查
if (doc) console.log('Data:', doc.data());
});⚠️ 注意事项:
- collection.doc(id).get() 是原子性单文档读取,不依赖任何自定义索引,100% 可靠;
- where('id', '==', id) 查询必须确保 id 字段已建立索引(若为自定义字段且未启用单字段索引,将触发索引缺失错误);
- 查询返回 QuerySnapshot,即使预期唯一结果,也需遍历 docs 数组并做空判断,增加出错风险;
- 若业务逻辑中 id 字段并非真实文档 ID(例如是业务生成的 UUID),请勿混淆二者语义——文档 ID 是 Firestore 元数据,而字段 id 是普通数据,二者无强制一致性。
? 总结:性能差异在真实场景中可忽略不计(毫秒级波动受网络延迟主导),但代码可读性、健壮性和维护成本差异显著。除非有特殊架构约束(如完全弃用文档 ID、统一用业务字段路由),否则应坚定采用 .doc(id).get() 方式——它更符合 Firestore 设计哲学,也更贴近“获取资源”的直觉语义。











