Как получить размер документа Firestore?

Из Документы 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);
});
Интеграция Angular - Firebase Analytics
Интеграция Angular - Firebase Analytics
Узнайте, как настроить Firebase Analytics и отслеживать поведение пользователей в вашем приложении Angular.
18
0
12 131
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Я искал ссылку на Firebase, ожидая, что метаданные будут иметь атрибут, но это не так. Вы можете проверить это здесь.

Так что мой следующий подход состоял бы в том, чтобы определить вес объекта как приближение. У библиотека sizeOf, кажется, есть разумный API для этого.

Так что это будет что-то вроде:

sizeof.sizeof(doc.data());

Я бы не стал использовать снимок документа, потому что он содержит метаданные, например, есть ли ожидающие сохранения. С другой стороны, в некоторых случаях переоценка может быть лучше.

[ОБНОВЛЕНИЕ] Спасибо Дугу Стивенсону за прекрасное понимание

Итак, мне было любопытно какая разница будет на самом деле, поэтому с моим неуклюжим js я сделал грязное сравнение, вы можете увидеть демо здесь

Учитывая этот объект:

 {
  "boolean": true,
  "number": 1,
  "text": "example"
  }

И без учета id вот результат:

| Method  | Bytes |
|---------|-------|
| FireDoc | 37    |
| sizeOf  | 64    |

Таким образом, библиотека sizeOf может быть хорошим предсказателем, если мы хотим переоценить (при условии, что расчеты в порядке и будут вести себя более или менее одинаково для более сложных объектов). Но, как поясняется в комментарии, это Грубая оценка.

Да. Я тоже этого ожидал. Но ничего не нашел.

cbdeveloper 27.05.2019 19:20

Я бы не стал доверять этой библиотеке sizeof как точному представлению размера документа Firestore. Размер объекта JS в памяти будет отличаться от размера документа, сохраненного в Firestore. Реализация объекта JS может сильно различаться в разных средах выполнения. Я бы использовал эту библиотеку только как очень приблизительную оценку. Я ожидал бы, что оценка будет более точной в случае больших строковых значений и менее точной, когда есть много полей различных неосновных типов.

Doug Stevenson 27.05.2019 19:25

@DougStevenson обновил ответ, было весело, надеюсь помочь

cutiko 27.05.2019 22:22
Ответ принят как подходящий

Вычисления, используемые для вычисления размера документа, полностью задокументированы здесь. Там много текста, поэтому, пожалуйста, перейдите туда, чтобы прочитать его. Не стоит копировать весь этот текст сюда.

Если вам приходится вручную вычислять размер документа по мере его роста, я считаю, что вы, вероятно, не масштабируете свои данные. Если у вас есть списки данных, которые могут неограниченно расти, вам, вероятно, не следует использовать поле списка, а вместо этого помещать эти данные в документы в новую коллекцию или вложенную коллекцию. Есть несколько исключений из этого правила, но, вообще говоря, вам не нужно беспокоиться о вычислении размера документа в клиентском коде.

Есть ли планы по выпуску кода для этих оценок? Было бы неплохо, если бы сообщество завладело этим.

DarkNeuron 03.09.2019 10:07

Есть случаи, когда такие данные были бы чрезвычайно полезны. Например, в случае приложения чата с большим количеством обменов сообщения могут быть объединены в меньшее количество документов, чтобы повысить производительность чтения, вплоть до безопасного значения. Текущее время загрузки истории чата в Angular для приложения чата, загружающего отдельные ответы из Firestore, оставляет желать лучшего.

Louis-Eric Simard 24.10.2019 03:33

Это обоюдоострая проблема, когда нам приходится выбирать между беспокойством о растущем размере документа и растущим числом документов. Добавление данных в один документ сэкономит время и затраты на поиск (чтение одного документа стоит), но мы должны беспокоиться о размере документа. Разделение данных на несколько документов поможет избежать ограничения размера документа, но увеличит время и стоимость поиска (стоимость чтения нескольких документов). ИМО, в метаданных документа должен быть атрибут размера документа.

MAW 12.01.2022 07:12

Я опубликовал 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 11.11.2020 07:00

@Pooja Да, это действительно так.

Alex Mamo 11.11.2020 15:20

Есть ли способ использовать это внутри Unity?

Jay 15.01.2021 15:07

@Jay Я не уверен, что вы можете использовать эту библиотеку внутри Unity. Никогда не пробовал это.

Alex Mamo 15.01.2021 21:50

Для пользователей 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 к общему количеству этой функции.

Iskeraet 06.05.2021 02:33

Вы можете использовать этот калькулятор (код обрезан), я пишу сам.

источник: 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>

Как сейчас написано, ваш ответ неясен. Пожалуйста, редактировать, чтобы добавить дополнительную информацию, которая поможет другим понять, как это относится к заданному вопросу. Дополнительную информацию о том, как писать хорошие ответы, можно найти в справочном центре.

Community 22.10.2021 17:33

Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. - Из обзора

Robert 22.10.2021 21:33

Поэтому я искал способ уменьшить количество ненужных чтений документов путем накопления данных в массивах и беспокоиться о размере.

Оказывается, я даже не был близок к пределу.

Вот что вы можете сделать, Создайте новую коллекцию и добавьте документ с наихудшим сценарием для оперативных данных и с помощью облачной консоли экспортируйте эту коллекцию, вы увидите размер документа.

Вот скриншот моего экспорта

Предполагая, что все документы имеют одинаковый размер, каждый составляет 0,0003 МБ.

Вы также можете увидеть, превышают ли документы ограничение в 1024 байта. документ превышает лимит из консоли

Примечание: вы можете экспортировать, только если вы включили биллинг.!

Другие вопросы по теме