You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:45:37