javascript - Angular 2+ 中的 Firebase 内部查询
问题描述
我是 Firebase 的新手。我现在正在尝试对我的集合执行查询,但我不知道如何。我有登录用户(登录后我有他的 ID)、类别和购买集合。
Category 集合有一个 userId 列,Purchase 有 CategoryId。
有了 userId,我如何查询该用户的购买集合?我应该以某种方式在 Purchase 和 Category 之间进行一种内部连接,其中 Category.UserId 等于我拥有的 UserId。
我该怎么做?
提前致谢。
这是我当前的代码,但它不起作用:
fetchAllPurchaseHistory(userId: string) {
this.fetchCategories()
const userDocRef = firebase.firestore()
.collection('User')
.doc(userId);
const categoriesDocRef = firebase.firestore()
.collection('Category').where('UserId', '==', userDocRef);
this.fbSubs.push(this.db.collection('Purchase', ref => ref.where('CategoryId', '==', categoriesDocRef))
.snapshotChanges()
.pipe(map(docArray => {
return docArray.map(doc => {
return {
Id: doc.payload.doc.id,
UserId: doc.payload.doc.data()['UserId'],
Description: doc.payload.doc.data()['Description'],
Address: doc.payload.doc.data()['Address'],
Establishment: doc.payload.doc.data()['Establishment'],
Price: doc.payload.doc.data()['Price'],
CreatedDate: doc.payload.doc.data()['CreatedDate']
};
});
})).subscribe((ps: Purchase[]) => {
this.store.dispatch(new Finance.SetPurchaseHistory(ps));
}));
}
解决方案
Firestore 没有开箱即用的内连接查询,因此要进行这种查询,您需要逐个查询文档以提取必要的信息以查询下一个文档,依此类推,事实上以代码方式进行连接。
我不清楚的一件事是 Category 集合中的 UserId 值和 Purchase 集合中的 CategoryId 是文档 ID 还是文档引用。假设它们是文档 ID,代码可能如下所示:
// Assume db is a firestore instance
function foo(userId) {
const categoryDoc = await db.collection('Category').where('UserId', '==', userId).get()
const categoryId = categoryDoc.id
const purchaseDoc = await db.collection('Purchase').where('CategoryId', '==', categoryId).get()
// Do whatever you need with the document
}
另外,在阅读您的描述后,我相信您来自 SQL 背景,并且您正在模拟表之间的关系,其中包含其他文档引用的文档字段。虽然这种方法对建模 1-Many 或 Many-1 关系很有用,但如果您发现简单的日常使用查询需要多个文档交叉引用,这通常意味着数据库应该采用不同的结构。
例如,一些常见的方法是:
- 让用户文档有一个类别或购买的子集合,以便您可以通过 userId 直接引用它们。
- 让购买文档有一个带有 userId 的字段(也可能是 categoryId),以便可以通过单个查询找到它。
- 在用户文档中内联采购文档。这可能是好/坏,具体取决于要存储的数据及其更新方式
有关此主题的更多信息,您可以查看 Firebase 频道中的视频,这些视频可以在 Youtube 或本文档页面中找到
推荐阅读
- apache - 使用 rewriterule 提取和重定向 MP3 文件
- php - 更改表单提交的参数语法
- c# - 动态访问 for 循环中的变量名
- php - 在 WooCommerce 中更改“选择一个选项”变体下拉标签
- json - 将 Laravel 响应解析为正确的 JSON
- ios - Swift 桥接头不导出 React Native 类型
- javascript - 如何使用 Rails UJS 设置超时?
- typescript - 如何添加额外的资源列 fullCalendar-scheduler
- sql - Access sql 将数字转换为 - 或 . 为保密
- css - 使用媒体查询时,Div 不适合浏览器的宽度