Google Firestore array_contains 查询失效问题求助
问题根源
Firestore的array-contains查询对象时,要求完全匹配对象的所有键值对。你现在查询的是{ ID: posilekId },但DietDays集合里Meals数组的元素肯定还包含Portions等其他字段,两者结构不一致,所以查不到匹配的文档。
解决方案
方案1:优化数据结构(推荐)
在DietDays文档里新增一个MealIDs数组,专门存储关联的Posilek ID字符串。这样查询时直接用array-contains匹配字符串,既高效又准确。
修改后的代码示例:
exports.updateDietDaysWhenMealChanges = functions.firestore.document("Posilek/{posilekId}").onUpdate((change, context) => { const posilekId = context.params.posilekId; const posilekAfter = change.after.data(); // 改为查询MealIDs数组包含posilekId的文档 return db.collection("DietDays").where("MealIDs", "array-contains", posilekId).get() .then(snapshot => { if (snapshot.empty) { functions.logger.log("No matching DietDay found"); return null; } else { return Promise.all(snapshot.docs.map(dietDayDoc => { const meals = dietDayDoc.data().Meals; const mealIndex = meals.findIndex(meal => meal.ID === posilekId); meals[mealIndex] = { ID: posilekId, Portions: posilekAfter.Portions }; functions.logger.log(`Editing meal in DietDay with ID: ${dietDayDoc.id}`); return dietDayDoc.ref.update({ Meals: meals }); })); } }); });
同时,记得在创建或更新DietDays文档时,同步维护MealIDs数组——添加Meal时把对应ID推入数组,删除Meal时移除对应ID。
方案2:内存过滤(不推荐大数据量场景)
如果暂时不想修改数据结构,可以先获取DietDays的所有文档,再在代码里过滤出符合条件的文档:
exports.updateDietDaysWhenMealChanges = functions.firestore.document("Posilek/{posilekId}").onUpdate((change, context) => { const posilekId = context.params.posilekId; const posilekAfter = change.after.data(); return db.collection("DietDays").get() .then(snapshot => { const matchingDocs = snapshot.docs.filter(doc => { const meals = doc.data().Meals; return meals.some(meal => meal.ID === posilekId); }); if (matchingDocs.length === 0) { functions.logger.log("No matching DietDay found"); return null; } else { return Promise.all(matchingDocs.map(dietDayDoc => { const meals = dietDayDoc.data().Meals; const mealIndex = meals.findIndex(meal => meal.ID === posilekId); meals[mealIndex] = { ID: posilekId, Portions: posilekAfter.Portions }; functions.logger.log(`Editing meal in DietDay with ID: ${dietDayDoc.id}`); return dietDayDoc.ref.update({ Meals: meals }); })); } }); });
注意:这种方法会读取DietDays集合的所有文档,数据量大时会消耗更多资源、性能下降,仅适合小数据集临时使用。
内容的提问来源于stack exchange,提问作者flicknba
相关产品推荐
相关产品推荐

