[英]How to get a Firestore document size?
从Firestore docs中,我们了解到 Firestore 文档的最大大小为:
文档的最大大小1 MiB (1,048,576 字节)
题
我如何知道单个文档的当前大小,以检查我是否接近 1mb 的限制?
例子:
var docRef = db.collection("cities").doc("SF");
docRef.get().then(function(doc) {
if (doc.exists) {
console.log("Document data:", doc.data());
// IS THERE A PROPERTY THAT CAN DISPLAY THE DOCUMENT FILE SIZE?
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
用于计算文档大小的计算在此处有完整记录。 那里有很多文字,所以请导航到那里阅读。 在这里复制所有文本是不值得的。
如果您必须在文档增长时手动计算其大小,我的观点是您可能没有对数据进行可扩展的建模。 如果您有可以无限增长的数据列表,您可能不应该使用列表字段,而是将该数据放在新集合或子集合中的文档中。 此规则有一些例外,但一般来说,您不必担心在客户端代码中计算文档的大小。
我发布了一个 npm包来计算 Firestore 文档的大小。
其他计算 JS 对象大小的包,如sizeof
或object-sizeof
不会给你一个精确的结果,因为 Firestore 中的一些原语具有不同的字节值。 例如,Js 中的 boolean 存储在 4 个字节中,在 Firestore 文档中存储为 1 个字节。 Null 是 0 个字节,在 Firestore 中它是 1 个字节。
除此之外,Firestore 还拥有自己独特的固定字节大小的类型:地理点、日期、参考。
引用是一个大对象。 像sizeof
这样的包将遍历 Reference 的所有方法/属性,而不是在这里做正确的事情。 即对文档名称的字符串值 + 其路径 + 16 个字节求和。 此外,如果 Reference 指向父 doc ,则sizeof
或object-sizeof
将不会在此处检测到循环引用,这可能比不正确的大小带来更大的麻烦。
对于想要根据最大1 MiB
(1,048,576 字节)配额检查文档大小的 Android 用户,我制作了一个库,可以帮助您计算:
这样,您就可以始终保持在限制之下。 这个库背后的算法是在关于Storage Size的官方文档中解释的算法。
我正在查看 Firebase 参考,期望元数据具有属性,但它没有。 你可以在这里查看。
所以我的下一个方法是将物体的重量计算为近似值。 sizeOf 库似乎有一个合理的 API。
所以它会是这样的:
sizeof.sizeof(doc.data());
我不会使用文档快照,因为它包含元数据,就像有待处理的保存一样。 另一方面,在某些情况下,高估可能会更好。
[更新] 感谢道格史蒂文森的精彩见解
所以我很好奇实际上会有多少差异,所以我用我笨重的 js 做了一个肮脏的比较,你可以在这里看到演示
考虑这个对象:
{
"boolean": true,
"number": 1,
"text": "example"
}
并打折id
这是结果:
| Method | Bytes |
|---------|-------|
| FireDoc | 37 |
| sizeOf | 64 |
因此,如果我们想要高估,sizeOf 库可能是一个很好的预测器(假设计算很好并且对于更复杂的实体或多或少地表现相同)。 但正如评论中所解释的,这是一个粗略的估计。
对于 Swift 用户,
如果您想估计文档大小,那么我使用以下方法。 以字节为单位返回文档的估计大小。 它不是 100% 准确,但给出了可靠的估计。 基本上只是将数据映射中的每个键、值转换为字符串并返回 String + 1 的总字节数。有关 Firebase 如何确定文档大小的详细信息,您可以查看以下链接: https ://firebase.google.com/docs/ firestore/存储大小。
func getDocumentSize(data: [String : Any]) -> Int{
var size = 0
for (k, v) in data {
size += k.count + 1
if let map = v as? [String : Any]{
size += getDocumentSize(data: map)
} else if let array = v as? [String]{
for a in array {
size += a.count + 1
}
} else if let s = v as? String{
size += s.count + 1
}
}
return size
}
你可以用这个计算器(代码剪掉了),我自己写的。
来源: https : //firebase.google.com/docs/firestore/storage-size
<!DOCTYPE html> <html> <head> <title>Calculte Firestore Size</title> </head> <body> <h1>Firestore Document Size Calculator</h1> <h2 id="response" style="color:red">This is a Heading</h2> <textarea id="id" style="width: 100%" placeholder="Firestore Doc Ref"></textarea> <textarea id="json" style="width: 100%; min-height: 200px" placeholder="Firestore Doc Value JSON STRING"></textarea> <textarea id="quantity" style="width: 100%;" placeholder="How Many repeat this value?"></textarea> <script> document.getElementById("json").value='{"type": "Personal","done": false , "priority": 1 , "description": "Learn Cloud Firestore"}' document.getElementById("id").value = 'users/jeff/tasks/my_task_id' calculate() function yuzdeBul(total,number) { if (number == 0) { return 0; } const sonuc = Math.ceil(parseInt(number) / (parseInt(total) / 100)); return sonuc; } function calculate(){ var quantity = parseInt(document.getElementById("quantity").value || 1); var firestoreId = document.getElementById("id").value; var refTotal = firestoreId .split("/") .map((v) => v.length + 1) .reduce((a, b) => a + b, 0) + 16; var idTotal = 0 //console.log(idTotal); var parseJson = JSON.parse(document.getElementById("json").value); idTotal += calculateObj(parseJson); idTotal+=32; idTotal*=quantity; idTotal+=refTotal; document.getElementById("response").innerHTML = idTotal + "/" + 1048576 + " %"+yuzdeBul(1048576,idTotal); } function calculateObj(myObj) { var total = Object.keys(myObj).map((key) => { var keySize = key.toString().length + 1; var findType = typeof myObj[key]; //console.log(key,findType) if (findType == "string") { keySize += myObj[key].length + 1; } else if (findType == "boolean") { keySize += 1; } if (findType == "number") { keySize += 8; } if (findType == "object") { keySize += calculateObj(myObj[key]); } return keySize; }); return total.reduce((a, b) => a + b, 0); } document.getElementById("json").addEventListener("change", calculate); document.getElementById("id").addEventListener("change", calculate); document.getElementById("quantity").addEventListener("change", calculate); </script> </body> </html>
所以我一直在寻找一种方法,通过在数组中积累数据来减少不必要的文档读取,并担心大小。
结果我什至没有接近极限。
这是您可以执行的操作,创建一个新集合并添加一个包含实时数据最坏情况的文档,然后使用云控制台导出该集合,您将看到文档大小。
假设所有文档大小相等,每个文档都是 0.0003MB
注意:您只有在启用计费后才能导出。!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.