我只是在探索新的Firebase Firestore,它包含一个称为引用的数据类型。我不清楚这是干什么的。
它像外键吗? 它可以用来指向位于其他地方的集合吗? 如果引用是一个实际的引用,我可以使用它查询吗?例如,我是否可以有一个直接指向用户的引用,而不是将userId存储在文本字段中?我可以使用这个用户引用进行查询吗?
我只是在探索新的Firebase Firestore,它包含一个称为引用的数据类型。我不清楚这是干什么的。
它像外键吗? 它可以用来指向位于其他地方的集合吗? 如果引用是一个实际的引用,我可以使用它查询吗?例如,我是否可以有一个直接指向用户的引用,而不是将userId存储在文本字段中?我可以使用这个用户引用进行查询吗?
当前回答
2022年更新
let coursesArray = [];
const coursesCollection = async () => {
const queryCourse = query(
collection(db, "course"),
where("status", "==", "active")
)
onSnapshot(queryCourse, (querySnapshot) => {
querySnapshot.forEach(async (courseDoc) => {
if (courseDoc.data().userId) {
const userRef = courseDoc.data().userId;
getDoc(userRef)
.then((res) => {
console.log(res.data());
})
}
coursesArray.push(courseDoc.data());
});
setCourses(coursesArray);
});
}
其他回答
迟来的是,这个博客有两个好处:
如果我希望按评分、发布日期或最多的赞来排序餐厅评论,我可以在评论子集合中做到这一点,而不需要复合索引。在更大的顶级集合中,我需要为其中的每一个创建一个单独的复合索引,而且我还有200个复合索引的限制。
我不会有200个综合指数,但有一些限制。
此外,从安全规则的角度来看,基于存在于父文档中的某些数据来限制子文档是相当常见的,当您将数据设置在子集合中时,这要容易得多。
例如,如果用户没有父字段的权限,则限制插入子集合。
如果不使用Reference数据类型,则需要更新每个文档。
例如,您有2个集合“categories”和“products”,并将类别名称“Fruits”存储到产品中“Apple”和“Lemon”的每个文档中,如下所示。但是,如果在categories中更新了categories名称“Fruits”,那么在product中每一个关于“Apple”和“Lemon”的文档中也需要更新category名称“Fruits”:
collection | document | field
categories > 67f60ad3 > name: "Fruits"
collection | document | field
products > 32d410a7 > name: "Apple", category: "Fruits"
58d16c57 > name: "Lemon", category: "Fruits"
但是,如果您将“Fruits”在categories中的引用存储到产品中“Apple”和“Lemon”的每个文档中,则当您在categories中更新类别名称“Fruits”时,您不需要更新“Apple”和“Lemon”的每个文档:
collection | document | field
products > 32d410a7 > name: "Apple", category: categories/67f60ad3
58d16c57 > name: "Lemon", category: categories/67f60ad3
这就是引用数据类型的优点。
根据#AskFirebase https://youtu.be/Elg2zDVIcLo?t=276 目前的主要用例是Firebase控制台UI中的链接
很多答案提到它只是对另一个文档的引用,但不返回该引用的数据,但我们可以使用它单独获取数据。
下面是如何在firebase JavaScript SDK 9模块化版本中使用它的示例。
让我们假设您的壁炉有一个名为products的集合,其中包含以下文档。
{
name: 'productName',
size: 'medium',
userRef: 'user/dfjalskerijfs'
}
在这里,用户有对用户集合中的文档的引用。我们可以使用下面的代码段获取产品,然后从引用检索用户。
import { collection, getDocs, getDoc, query, where } from "firebase/firestore";
import { db } from "./main"; // firestore db object
let productsWithUser = []
const querySnaphot = await getDocs(collection(db, 'products'));
querySnapshot.forEach(async (doc) => {
let newItem = {id: doc.id, ...doc.data()};
if(newItem.userRef) {
let userData = await getDoc(newItem.userRef);
if(userData.exists()) {
newItem.userData = {userID: userData.id, ...userData.data()}
}
productwithUser.push(newItem);
} else {
productwithUser.push(newItem);
}
});
这里的集合,getDocs, getDoc,查询,其中是与firestore相关的模块,我们可以在必要时使用它来获取数据。我们使用从产品文档返回的用户引用直接获取该引用的用户文档,使用以下代码:
let userData = await getDoc(newItem.userRef);
要阅读更多关于如何使用模块化ver SDK参考官方文档了解更多。
对于那些寻找通过引用查询的Javascript解决方案的人来说,概念是,你需要在查询语句中使用一个“文档引用”对象
teamDbRef = db.collection('teams').doc('CnbasS9cZQ2SfvGY2r3b'); /* CnbasS9cZQ2SfvGY2r3b being the collection ID */
//
//
db.collection("squad").where('team', '==', teamDbRef).get().then((querySnapshot) => {
//
}).catch(function(error) {
//
});
(答案在这里:https://stackoverflow.com/a/53141199/1487867)