# #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));
});