AngularFire2下Firestore查询仅获取文档ID的费用疑问
你的理解完全正确!
你担心的点没错——这段代码确实会触发所有匹配文档的完整读取操作,哪怕你只访问了doc.id。原因是:当onSnapshot触发时,Firestore已经把查询匹配到的全部文档内容从服务器拉取到了客户端的本地快照里,后续访问doc.id只是从本地缓存的快照中读取数据,不会再发起新请求,但初始的请求已经完整获取了每个文档,所以每个匹配的文档都会被计入一次读取费用。
怎么优化?只获取文档ID来减少数据传输
虽然Firestore的读取费用是按文档数量计算的(哪怕只读取文档的一部分,也算一次读取),但你可以通过投影查询来只请求文档ID对应的字段,这样能减少传输的数据量,同时明确你的需求。Firestore内部用__name__字段来存储文档ID,你可以通过select()方法指定只获取这个字段:
db.collection("cities", ref => ref .where("capital", "==", true) .select("__name__") // 仅请求文档ID对应的字段 ).onSnapshot(querySnapshot => { querySnapshot.forEach(doc => { console.log(doc.id); // 依然可以正常获取文档ID }); });
这样修改后,Firestore只会返回包含文档ID的最小数据 payload,虽然每个匹配的文档还是会算一次读取,但传输的数据量会大幅减少,这在文档内容较大时会很有帮助。
额外提醒
如果你的核心目标是减少读取次数(而不只是减少传输数据),那这种方式帮不上忙——因为只要查询返回了某个文档,就会被计入一次读取。这种情况下,你可能需要重新设计数据结构,比如把需要查询的文档ID提前存储到一个单独的集合或字段中,这样可以直接查询那个集合来获取ID,避免读取原文档。
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

