我只是在探索新的Firebase Firestore,它包含一个称为引用的数据类型。我不清楚这是干什么的。
它像外键吗? 它可以用来指向位于其他地方的集合吗? 如果引用是一个实际的引用,我可以使用它查询吗?例如,我是否可以有一个直接指向用户的引用,而不是将userId存储在文本字段中?我可以使用这个用户引用进行查询吗?
我只是在探索新的Firebase Firestore,它包含一个称为引用的数据类型。我不清楚这是干什么的。
它像外键吗? 它可以用来指向位于其他地方的集合吗? 如果引用是一个实际的引用,我可以使用它查询吗?例如,我是否可以有一个直接指向用户的引用,而不是将userId存储在文本字段中?我可以使用这个用户引用进行查询吗?
当前回答
迟来的是,这个博客有两个好处:
如果我希望按评分、发布日期或最多的赞来排序餐厅评论,我可以在评论子集合中做到这一点,而不需要复合索引。在更大的顶级集合中,我需要为其中的每一个创建一个单独的复合索引,而且我还有200个复合索引的限制。
我不会有200个综合指数,但有一些限制。
此外,从安全规则的角度来看,基于存在于父文档中的某些数据来限制子文档是相当常见的,当您将数据设置在子集合中时,这要容易得多。
例如,如果用户没有父字段的权限,则限制插入子集合。
其他回答
引用很像外键。
当前发布的sdk不能存储对其他项目的引用。在项目中,引用可以指向任何其他集合中的任何其他文档。
您可以像使用任何其他值一样在查询中使用引用:用于过滤、排序和分页(startAt/startAfter)。
与SQL数据库中的外键不同,引用对于在单个查询中执行连接没有用处。您可以使用它们进行依赖查找(看起来像是连接),但要小心,因为每次跳转都会导致到服务器的另一次往返。
如果不使用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
这就是引用数据类型的优点。
在Firestore中添加下面对我有用的引用。
As the other answers say, it's like a foreign key. The reference attribute doesn't return the data of the reference doc though. For example, I have a list of products, with a userRef reference as one of the attributes on the product. Getting the list of products, gives me the reference of the user that created that product. But it doesn't give me the details of the user in that reference. I've used other back end as a services with pointers before that have a "populate: true" flag that gives the user details back instead of just the reference id of the user, which would be great to have here (hopefully a future improvement).
下面是一些示例代码,我用来设置引用以及获得产品列表集合,然后从给定的用户引用id获得用户详细信息。
在集合上设置引用:
let data = {
name: 'productName',
size: 'medium',
userRef: db.doc('users/' + firebase.auth().currentUser.uid)
};
db.collection('products').add(data);
获取一个集合(产品)和每个文档上的所有引用(用户详细信息):
db.collection('products').get()
.then(res => {
vm.mainListItems = [];
res.forEach(doc => {
let newItem = doc.data();
newItem.id = doc.id;
if (newItem.userRef) {
newItem.userRef.get()
.then(res => {
newItem.userData = res.data()
vm.mainListItems.push(newItem);
})
.catch(err => console.error(err));
} else {
vm.mainListItems.push(newItem);
}
});
})
.catch(err => { console.error(err) });
对于那些寻找通过引用查询的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)
根据#AskFirebase https://youtu.be/Elg2zDVIcLo?t=276 目前的主要用例是Firebase控制台UI中的链接