Из Документы Firestore мы получаем, что максимальный размер документа Firestore:
Maximum size for a document 1 MiB (1,048,576 bytes)
ВОПРОС
Как я могу узнать текущий размер одного документа, чтобы проверить, приближаюсь ли я что ограничение в 1 мб?
Пример:
var docRef = db.collection("cities").doc("SF");
docRef.get().then(function(doc) {
if (doc.exists) {
console.info("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.info("No such document!");
}
}).catch(function(error) {
console.info("Error getting document:", error);
});
Я искал ссылку на Firebase, ожидая, что метаданные будут иметь атрибут, но это не так. Вы можете проверить это здесь.
Так что мой следующий подход состоял бы в том, чтобы определить вес объекта как приближение. У библиотека sizeOf, кажется, есть разумный API для этого.
Так что это будет что-то вроде:
sizeof.sizeof(doc.data());
Я бы не стал использовать снимок документа, потому что он содержит метаданные, например, есть ли ожидающие сохранения. С другой стороны, в некоторых случаях переоценка может быть лучше.
[ОБНОВЛЕНИЕ] Спасибо Дугу Стивенсону за прекрасное понимание
Итак, мне было любопытно какая разница будет на самом деле, поэтому с моим неуклюжим js я сделал грязное сравнение, вы можете увидеть демо здесь
Учитывая этот объект:
{
"boolean": true,
"number": 1,
"text": "example"
}
И без учета id
вот результат:
| Method | Bytes |
|---------|-------|
| FireDoc | 37 |
| sizeOf | 64 |
Таким образом, библиотека sizeOf может быть хорошим предсказателем, если мы хотим переоценить (при условии, что расчеты в порядке и будут вести себя более или менее одинаково для более сложных объектов). Но, как поясняется в комментарии, это Грубая оценка.
Я бы не стал доверять этой библиотеке sizeof как точному представлению размера документа Firestore. Размер объекта JS в памяти будет отличаться от размера документа, сохраненного в Firestore. Реализация объекта JS может сильно различаться в разных средах выполнения. Я бы использовал эту библиотеку только как очень приблизительную оценку. Я ожидал бы, что оценка будет более точной в случае больших строковых значений и менее точной, когда есть много полей различных неосновных типов.
@DougStevenson обновил ответ, было весело, надеюсь помочь
Вычисления, используемые для вычисления размера документа, полностью задокументированы здесь. Там много текста, поэтому, пожалуйста, перейдите туда, чтобы прочитать его. Не стоит копировать весь этот текст сюда.
Если вам приходится вручную вычислять размер документа по мере его роста, я считаю, что вы, вероятно, не масштабируете свои данные. Если у вас есть списки данных, которые могут неограниченно расти, вам, вероятно, не следует использовать поле списка, а вместо этого помещать эти данные в документы в новую коллекцию или вложенную коллекцию. Есть несколько исключений из этого правила, но, вообще говоря, вам не нужно беспокоиться о вычислении размера документа в клиентском коде.
Есть ли планы по выпуску кода для этих оценок? Было бы неплохо, если бы сообщество завладело этим.
Есть случаи, когда такие данные были бы чрезвычайно полезны. Например, в случае приложения чата с большим количеством обменов сообщения могут быть объединены в меньшее количество документов, чтобы повысить производительность чтения, вплоть до безопасного значения. Текущее время загрузки истории чата в Angular для приложения чата, загружающего отдельные ответы из Firestore, оставляет желать лучшего.
Это обоюдоострая проблема, когда нам приходится выбирать между беспокойством о растущем размере документа и растущим числом документов. Добавление данных в один документ сэкономит время и затраты на поиск (чтение одного документа стоит), но мы должны беспокоиться о размере документа. Разделение данных на несколько документов поможет избежать ограничения размера документа, но увеличит время и стоимость поиска (стоимость чтения нескольких документов). ИМО, в метаданных документа должен быть атрибут размера документа.
Я опубликовал npm упаковка, который вычисляет размер документа Firestore.
Другие пакеты, такие как sizeof
или object-sizeof
, которые вычисляют размер объекта JS, не дадут вам точного результата, потому что некоторые примитивы в Firestore имеют другое значение байта. Например, логическое значение в Js хранится в 4 байтах, в документе Firestore — в 1 байте. Null — это 0 байт, в Firestore — 1 байт.
Кроме того, у Firestore есть собственные уникальные типы с фиксированным размером байта: Geo point, Date, Reference.
Ссылка — это большой объект. Такие пакеты, как sizeof
, будут проходить через все методы/свойства Reference, а не просто делать правильные вещи здесь. То есть суммировать строковое значение имени документа + путь к нему + 16 байт. Кроме того, если ссылка указывает на родительский документ, sizeof
или object-sizeof
не обнаружат здесь циклическую ссылку, что может создать еще большую проблему, чем неправильный размер.
Для пользователей Android, которые хотят сравнить размер документа с максимальной квотой 1 MiB
(1 048 576 байт), я создал библиотеку, которая может помочь вам рассчитать это:
Таким образом, вы всегда сможете оставаться ниже лимита. Алгоритм этой библиотеки описан в официальной документации по Размер хранилища.
Это очень просто и полезно.
@Pooja Да, это действительно так.
Есть ли способ использовать это внутри Unity?
@Jay Я не уверен, что вы можете использовать эту библиотеку внутри Unity. Никогда не пробовал это.
Для пользователей 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
}
Firebase также включает «32 дополнительных байта» на документ плюс размер имени документа (около 30 по умолчанию), поэтому добавьте ~ 60 к общему количеству этой функции.
Вы можете использовать этот калькулятор (код обрезан), я пишу сам.
источник: https://firebase.google.com/docs/firestore/размер хранилища
<!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.info(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.info(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,0003 МБ.
Вы также можете увидеть, превышают ли документы ограничение в 1024 байта. документ превышает лимит из консоли
Примечание: вы можете экспортировать, только если вы включили биллинг.!
Да. Я тоже этого ожидал. Но ничего не нашел.