Запрос со ссылкой в firestore

# #node.js #firebase #google-cloud-firestore

Вопрос:

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

 const childOrgReference = db.collection(`organisations/${context.params.orgId}/childOrganisations`).doc(context.params.childOrgId);
    // Find all people with corresponding childOrgReference
    db.collection(`organisations/${context.params.orgId}/people`).where("childOrgReference", '==', childOrgReference).get()
        .then(function(querySnapshot) {
          querySnapshot.forEach(function(docu) {
            db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id).update({
              "isDeleted": true,
            });
          });
        });
 

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

 // const childOrgReference = db.collection(`organisations/${context.params.orgId}/childOrganisations`).doc(context.params.childOrgId);
    // Find all people with corresponding childOrgReference
    db.collection(`organisations/${context.params.orgId}/people`).where("childOrgReference.id", '==', context.params.childOrgId).get()
        .then(function(querySnapshot) {
          querySnapshot.forEach(function(docu) {
            db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id).update({
              "isDeleted": true,
            });
          });
        });
 

Кто-нибудь имеет хоть малейшее представление о том, что я делаю не так?


Изменить: это текущий код, который у меня есть:

 const childOrgReference = db.collection(`organisations/${context.params.orgId}/childOrganisations`).doc(context.params.childOrgId);
    logger.log(childOrgReference);

    // Find all people with corresponding childOrgReference
    db.collection(`organisations/${context.params.orgId}/people`)
        .where("childOrgReference", '==', childOrgReference)
        .get()
        .then(function(querySnapshot) {
          const updates = [];
          querySnapshot.forEach(function(docu) {
            logger.log(docu.id);
            const docuRef = db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id);
            updates.push(docuRef.update({"isDeleted": true}));
          });

          Promise.all(updates).then(() => {
            console.log("Documents Updated");
          }).catch((e) => console.log(e));
        });
 

Ведение журнала ссылка регистрирует следующее:

 DocumentReference {
  _firestore: Firestore {
    _settings: {
      projectId: 'fmis-online-dev',
      firebaseVersion: '9.6.0',
      libName: 'gccl',
      libVersion: '4.9.9 fire/9.6.0',
      ignoreUndefinedProperties: true
    },
    _settingsFrozen: true,
    _serializer: Serializer {
      createReference: [Function],
      createInteger: [Function],
      allowUndefined: true
    },
    _projectId: 'fmis-online-dev',
    registeredListenersCount: 0,
    bulkWritersCount: 0,
    _backoffSettings: { initialDelayMs: 100, maxDelayMs: 60000, backoffFactor: 1.3 },
    _clientPool: ClientPool {
      concurrentOperationLimit: 100,
      maxIdleClients: 1,
      clientFactory: [Function],
      clientDestructor: [Function],
      activeClients: Map {},
      failedClients: Set {},
      terminated: false,
      terminateDeferred: [Deferred]
    }
  },
  _path: ResourcePath {
    segments: [
      'organisations',
      '3dkI69YGRE20AMn9oNGL',
      'childOrganisations',
      'bunEfTrEjtNxaBlpT2zk'
    ]
  },
  _converter: {
    toFirestore: [Function: toFirestore],
    fromFirestore: [Function: fromFirestore]
  }
} 
 

Это ссылка, отображаемая в консоли firestore:
введите описание изображения здесь

Проблема в том, что документ «Люди» не найден. Идентификатор не регистрируется. Я понятия не имею, где это идет не так, но я подозреваю, что ссылка в документе «Люди» может быть неверной. Однако я не знаю, каким он должен быть.

Ответ №1:

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

 const childOrgReference = db.collection(`organisations/${context.params.orgId}/childOrganisations`).doc(context.params.childOrgId);

// Find all people with corresponding childOrgReference
db.collection(`organisations/${context.params.orgId}/people`)
  .where("childOrgReference", '==', childOrgReference)
  .get()
  .then(function (querySnapshot) {
    const updates = []
    querySnapshot.forEach(function (docu) {
      const docuRef = db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id) 
      updates.push(docuRef.update({"isDeleted": true});
    });
  
    Promise.all(updates).then(() => {
      console.log("Documents Updated")
    }).catch(e => console.log(e))
  });
 

Вы также можете использовать пакетные записи вместо выполнения нескольких обещаний.

 const updatesBatch = db.batch()
querySnapshot.forEach(function (docu) {
      const docuRef = db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id) 
      updatesBatch.update(docuRef, {"isDeleted": true});
    });
})
updatesBatch.commit().then(() => console.log("Updated"))
 

Если ни один документ не соответствует вашему запросу, то, возможно, в ссылке, которую вы ищете, есть какое-либо несоответствие.

Комментарии:

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

2. @ThomasSmeman да, вы храните неправильную ссылку в childOrgReference поле в документе в подколлекции «Люди». В organisations/3dkI69YGRE20AMn9oNGL/childOrganisations/bunEfTrEjtNxaBlpT2zk противном случае ссылка должна быть childOrganisations как коллекция корневого уровня, а не как вложенная коллекция внутри organisations.

Ответ №2:

Таким образом, как заявил @Dharmaraj, ссылка на ребенка в документе «Люди» была неверной. Я исправил это, запросив не полный путь, а только вложенную коллекцию. Итак, рабочий код, который у меня есть, таков:

 const childOrgReference = db.collection(`childOrganisations`).doc(context.params.childOrgId);
    logger.log(childOrgReference);

    // Find all people with corresponding childOrgReference
    db.collection(`organisations/${context.params.orgId}/people`)
        .where("childOrgReference", '==', childOrgReference)
        .get()
        .then(function(querySnapshot) {
          const updates = [];
          querySnapshot.forEach(function(docu) {
            logger.log(docu.id);
            const docuRef = db.collection(`organisations/${context.params.orgId}/people`).doc(docu.id);
            updates.push(docuRef.update({"isDeleted": true}));
          });

          Promise.all(updates).then(() => {
            console.log("Documents Updated");
          }).catch((e) => console.log(e));
        });