Как сохранить документ с динамическим c идентификатором в Cloud Firestore? Всегда меняется - PullRequest
3 голосов
/ 22 января 2020

Я использую Cloud Firestore в качестве своей базы данных. Это мои коды форм на моей веб-странице, которые создают новый документ в мою коллекцию Cloud Firestore под названием "esequiz". Итак, как мне закодировать его таким образом, чтобы оно всегда плюс 1 к количеству документов в базе данных? А также установить ограничение на количество документов в базе данных

form.addEventListener('submit', (e) => {
e.preventDefault();
db.collection('esequiz').add({
    question: form.question.value,
    right: form.right.value,
    wrong: form.wrong.value
});
form.question.value = '';
form.right.value = '';
form.wrong.value = '';
});

В настоящее время это работает, но будет отображаться как автоматически сгенерированный идентификатор. Как мне сделать так, чтобы это продолжалось по номерам, как в моих текущих документах? Когда я сохраняю, я хотел бы, чтобы он прочитал текущий идентификатор последнего документа, ИЛИ просто посчитал количество документов, а затем просто + 1 enter image description here

Insight от Андрея Куснира, считая документы в Облачное хранилище пожаров не поддерживается.

Сейчас я пробую подход Андрея 2 - запрашивать документы в порядке убывания, а затем использовать .limit для получения только первого.

ОБНОВЛЕНО

form.addEventListener('submit', (e) => {
e.preventDefault();
let query = db.collection('esequiz');
let getvalue = query.orderBy('id', 'desc').limit(1).get();
let newvalue = getvalue + 1;
db.collection('esequiz').doc(newvalue).set({
    question: form.question.value,
    right: form.right.value,
    wrong: form.wrong.value
});
form.question.value = '';
form.right.value = '';
form.wrong.value = '';
});

Больше ошибок нет, но вместо этого приведенный ниже код возвращает [обещание объекта]

let getvalue = query .orderBy ('id', 'des c'). limit (1) .get ();

Поэтому, когда моя форма сохраняется, она сохраняется как [объект Promise] 1, который я не знаю, почему это так. Может кто-нибудь посоветовать мне, как вернуть значение идентификатора документа вместо [объекта Promise]

Я думаю, это потому, что я действительно указал, что нужно извлекать идентификатор документа в качестве значения, как мне это сделать? enter image description here

ОБНОВЛЕНО: ФИНАЛЬНОЕ РЕШЕНИЕ

Поиграл с кодами от Андрея, и вот последние коды, которые работают. Большое спасибо Андрею!

let query = db.collection('esequiz');
//let getvalue = query.orderBy('id', 'desc').limit(1).get();
//let newvalue = getvalue + 1;    
query.orderBy('id', 'desc').limit(1).get().then(querySnapshot => {
    querySnapshot.forEach(documentSnapshot => {
        var newID = documentSnapshot.id;
        console.log(`Found document at ${documentSnapshot.ref.path}`);
        console.log(`Document's ID: ${documentSnapshot.id}`);
        var newvalue = parseInt(newID, 10) + 1;
        var ToString = ""+ newvalue;
        db.collection('esequiz').doc(ToString).set({
            id: newvalue,
            question: form.question.value,
            right: form.right.value,
            wrong: form.wrong.value
        });
    });
    });

Ответы [ 2 ]

2 голосов
/ 27 января 2020

Если я правильно понял, вы добавляете данные в Cloud Firestore, и каждый новый документ будет иметь в качестве имени инкрементный номер.

Если вы запросите все документы, а затем посчитаете, сколько из них, то у вас будет много чтений документов по мере увеличения базы данных. Не забывайте, что Cloud Firestore взимает плату за каждый документ для чтения и записи, поэтому, если у вас есть 100 документов и вы хотите добавить новый документ с идентификатором: 101, то при первом чтении всех документов, а затем их подсчете, будет стоить вам 100 читает, а затем 1 пишет. В следующий раз это будет стоить 101 чтение и 1 запись. И он будет go включаться по мере увеличения вашей базы данных.

Я вижу два разных подхода:

Подход 1:

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

например,

The structure of the database:
esequiz:
        0: 
          last_document: 2
        1: 
          question: "What is 3+3?
          right: "6"
          wrong: "0"
        2: 
          question: "What is 2+3?
          right: "5"
          wrong: "0"

Таким образом, процесс будет go следующим образом:

  1. Прочитать документ "/ esequiz / 0" Считается как 1 READ
  2. Создать новый документ с идентификатором: last_document + 1 Считается как 1 ЗАПИСЬ
  3. Обновите документ, содержащий информацию: last_document = 3; Считается как 1 ЗАПИСЬ

Такой подход обойдется вам в 1 ЧИТАНИЕ и 2 ЗАПИСИ в базу данных.

Подход 2:

Вы можете загрузить только последний документ из базы данных и получить его идентификатор.

например

The structure of the database (Same as before, but without the additional doc):
esequiz:
        1: 
          question: "What is 3+3?
          right: "6"
          wrong: "0"
        2: 
          question: "What is 2+3?
          right: "5"
          wrong: "0"

Таким образом, процесс будет go следующим образом:

  1. Прочитайте последний документ, используя подход, описанный в Заказ и ограничение данных с помощью документации Cloud Firestore . Таким образом, вы можете использовать direction=firestore.Query.DESCENDING с комбинацией limit(1), которая даст вам последний документ. Считается как 1 READ
  2. Теперь вы знаете идентификатор загруженного документа, чтобы вы могли создать новый документ с идентификатором: он будет использовать загруженное значение и увеличит его на 1. Подсчитывает как 1 ЗАПИСЬ

Такой подход обойдется вам в 1 ЧИТАЙТЕ и 1 ЗАПИСИ в общей сложности в базу данных.


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

ОБНОВЛЕНИЕ

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

Структура базы данных:

esequiz:
        1: 
          id: 1
          question: "What is 3+3?
          right: "6"
          wrong: "0"
        2: 
          id:2
          question: "What is 2+3?
          right: "5"
          wrong: "0"

Как видите, идентификатор установлен так же, как идентификатор документа.

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

const {Firestore} = require('@google-cloud/firestore');
const firestore = new Firestore();

async function getLastDocument(){

    let query = firestore.collection('esequiz');

    query.orderBy('id', 'desc').limit(1).get().then(querySnapshot => {
    querySnapshot.forEach(documentSnapshot => {
        console.log(`Found document at ${documentSnapshot.ref.path}`);
        console.log(`Document's ID: ${documentSnapshot.id}`);
    });
    });

}

OUTPUT:
Found document at esequiz/2
Document's ID: 2

Затем вы можете взять идентификатор и увеличить его на 1, чтобы сгенерировать имя для вашего нового документа!

ОБНОВЛЕНИЕ 2

Итак, первоначальный вопрос о том, «Как хранить данные в облачном хранилище файлов с документами, имеющими инкрементный идентификатор», в тот момент, когда вы сталкиваетесь с проблемами настройки Firestore с вами проект. К сожалению, новые поднятые вопросы следует обсудить в другом посте Stackoverflow, поскольку они не имеют ничего общего с логикой c наличия дополнительных идентификаторов для документа, и лучше оставить один вопрос на вопрос, чтобы обеспечить лучшую поддержку сообщества для участников. которые ищут решение по конкретным вопросам. Поэтому в этом посте я постараюсь помочь вам выполнить простой сценарий Node.js и решить начальную проблему, которая заключается в сохранении документов Cloud Firestore с инкрементными идентификаторами. Все остальное, о том, как настроить это в вашем проекте и как использовать эту функцию на вашей странице, должно быть рассмотрено в дополнительном вопросе, где вам также потребуется предоставить как можно больше информации об используемой платформе, о настройке проекта. и др c.

Итак, давайте создадим простое приложение. js работаем с логикой c, описанной выше:

  1. Поскольку у вас уже работает Cloud Firestore, это означает, что у вас уже есть проект Google Cloud Platform (где используется Firestore) и уже включены соответствующие API. В противном случае он не будет работать .
  2. Ваше руководство в этом руководстве - Cloud Firestore: Node.js Клиент Документация. Это поможет вам понять все методы, которые вы можете использовать с Firestore Node.js API. Вы можете найти полезные ссылки для добавления, чтения, запроса документов и многих других операций. ( Я опубликую весь рабочий код позже на этих шагах. Я просто поделился ссылкой, чтобы вы знали, где искать дополнительные функции )
  3. Go до Панель управления консоли Google Cloud стр. Вы должны войти в свою учетную запись Google, где настроен ваш проект с базой данных Firestore.
  4. В правом верхнем углу вы должны увидеть 4 кнопки и изображение вашего профиля. Первая кнопка - Activate Cloud Shell . Это откроет терминал внизу страницы с уже установленной ОС linux и Google Cloud SDK. Там вы можете взаимодействовать со своими ресурсами в проектах GCP и локально тестировать свой код, прежде чем использовать его в своих проектах.
  5. После нажатия этой кнопки вы заметите, что терминал откроется внизу вашей страницы.
  6. Чтобы убедиться, что вы правильно аутентифицированы, мы настроим проект и снова аутентифицируем учетную запись, даже если это уже сделано по умолчанию. Поэтому сначала выполните $ gcloud auth login
  7. . В ответ на запрос введите Y и нажмите Enter
  8. Нажмите на созданную ссылку и подтвердите свою учетную запись в окне запроса
  9. Скопируйте Сгенерируйте строку обратно в терминал и нажмите Enter. Теперь вы должны пройти аутентификацию.
  10. Затем настройте проект, содержащий базу данных Cloud Firestore, с помощью следующей команды: $ gcloud config set project PROJECT_ID. Теперь вы готовы создать простое приложение. js сценарий и выполнить его.
  11. Создать новое приложение. js файл: nano app.js
  12. Вставить пример моего кода, который может найти в этой ссылке на GitHub . Он содержит полностью рабочий пример и множество комментариев, поясняющих каждую часть, поэтому лучше, чтобы он передавался через ссылку GitHub, а не вставлялся сюда. Без каких-либо изменений этот код будет выполнять именно то, что вы пытаетесь сделать. Я проверил это сам, и он работает.
  13. Выполните скрипт как: node app.js
  14. Это выдаст вам следующую ошибку:

    Ошибка: не удается найти модуль '@ google-cloud / firestore'

Поскольку мы импортируем библиотеку @google-cloud/firestore, но еще не установили ее.

Установить @google-cloud/firestore библиотеку следующим образом: $ npm i @google-cloud/firestore. Описано в DO C. Выполните скрипт еще раз: $ node app.js. Вы должны увидеть, например, Document with ID: 3 is written. Если вы выполните снова, вы должны увидеть, например, Document with ID: 4 is written.

Все эти изменения должны появиться в вашей базе данных Cloud Firestore также. Как вы можете видеть, он загружает идентификатор последнего документа, создает новый идентификатор, а затем создает новый документ с заданными аргументами, используя новый сгенерированный идентификатор в качестве имени документа. Это как раз то, о чем была первоначальная проблема.

Итак, я поделился с вами полным кодом, который работает и делает именно то, что вы пытаетесь сделать. К сожалению, другие недавно возникшие проблемы должны быть рассмотрены в другой публикации Stackoverflow, поскольку они не имеют ничего общего с первоначальной проблемой, а именно «Как создавать документы с инкрементным идентификатором». Я рекомендую вам следовать инструкциям и иметь рабочий пример, а затем попытаться реализовать logi c в вашем проекте. Однако, если у вас все еще есть проблемы с настройкой Firestore в вашем проекте, вы можете задать другой вопрос. После этого вы можете объединить оба решения и у вас будет рабочее приложение!

Удачи!

0 голосов
/ 22 января 2020

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

Но могут быть альтернативы, чтобы получить требуемое число.

  1. Начните сохранять идентификатор в записи и сделайте запрос с пределом 1 и сортировкой по убыванию по идентификатору.
  2. Сохраните последний номер в другой коллекции и увеличивайте его каждый раз, когда вы создаете новую запись, И извлекать то же самое всякий раз, когда необходимо.

Эти методы могут не работать, если параллельные запросы выполняются без транзакций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...