问题描述
我是 Firebase Cloud Firestore 的新手,需要帮助理解一下。
每个“餐厅”文档都包含自己的“产品”子集合。
在这里,我想运行一个查询以按不同的方式获取所有产品 包含“咖啡”标签且位于特定区域的餐厅 密码“234144”。
我尝试通过向特定餐厅拥有的每个产品添加 Pincode 来尝试集合组查询,但更改 Pincode 会花费很多,因为我猜所有产品都必须进行编辑。
是否有任何有效的方法可以做到这一点,或者在这方面是不可能的 以有效的方式使用数据库?
请告诉我您的想法...谢谢。
解决方法
如果我理解正确,您想检索具有特定标签和密码的所有产品(我认为这类似于邮政编码?)。我真的只有两种选择:
集合组查询
正如您所提到的,您可以将 tag 和 pincode 存储在 product 文档中。然后沿着这些行执行单个集合组查询(原谅 javascript,但我不熟悉 Dart,它应该非常相似):
var products = await firestore.collectionGroup('products')
.where('tag','==','coffee')
.where('pincode','234144').get();
正如您所指出的,使用此解决方案您需要在每个产品中保留pincode 这段数据是重复的,感觉应该避免它是正常的因为它既浪费又危险(可能会不同步),但这是要走的路!这称为非规范化。这在 this video by Todd Kerpelman 中有很好的解释。
然后,您可以创建一个由 restaurant 更新触发的云函数,以使 products 中的 pincode 与相应的 pincode 保持同步在餐厅
先查询餐厅,再查询产品
要仅保留餐厅中的pincode,您必须分两步进行查询:首先过滤特定密码中的餐厅,然后按标签过滤产品:
// 1 - retrieve restaurants in specific pincode
var restaurants = await firestore.collection('restaurants').where('pincode','234144').get();
// 2 - For each retrieved restaurant,retrieve all products matching the tag
var products = [];
for(let i = 0; i < restaurants.docs.length; ++i) {
var p = await restaurants.docs[i].collection("products").where("tag","==","coffee");
products.push(p);
}
使用此方法,无需在每个产品中重复pincode,但是您的查询不太理想,因为您加载了可能无用的餐厅不在您的密码中提供咖啡。