我正在使用Cloud Firestore作为数据库,并且有users
的集合,这些集合存储了有关用户的基本信息,例如ID,姓名,姓氏,电子邮件,公司ID。
我也收藏了companies
,在每个公司中我收藏了tasks
。
在每个任务中,我从用户集合中分配了一个用户(用户数据已复制,因此该用户的数据与集合users
中的用户相同)
问题是,当我从集合users
更新用户(更改名称或电子邮件...)时,因为已复制数据,而该特定用户在tasks
集合中未更改数据。
在更新集合users
中的用户以自动更新tasks
集合中的用户时,是否可以使用firestore?
答案 0 :(得分:1)
这在NoSQL数据库中是非常标准的情况,在该情况下,我们经常对数据进行非规范化,并且需要保持这些数据同步。
基本上,您有两种可能的主要方法:
更新“用户”文档时,请同时更新包含用户详细信息的其他文档(即“任务”)。您应该使用batched write来做到这一点:一批写操作是原子完成的,可以写到多个文档。
以下内容:
// Get a new write batch
var batch = db.batch();
var userRef = db.collection('users').doc('...');
batch.update(userRef, {name: '....', foo: '....'});
let userTaskRef = db.collection('companies').doc('...').collection('tasks').doc('taskId1');
batch.update(userTaskRef, {name: '....'});
userTaskRef = db.collection('companies').doc('...').collection('tasks').doc('taskId2');
batch.update(userTaskRef, {name: '....'});
// ...
// Commit the batch
batch.commit().then(function () {
// ...
});
请注意,您需要知道哪些是“其他(“任务”)文档,其中包含用户的详细信息”:您可能需要执行查询以获取这些文档(及其DocumentReference
)。 / p>
编写并部署Cloud Function,该data type在任何“用户”文档更新时触发,并采用该“用户”文档的值并更新包含用户详细信息的“任务”文档。
与第一种方法类似,在这种情况下,您还需要知道哪些是包含用户详细信息的“其他”(“任务”)文档。
在您的注释之后(“是否有其他选项可以引用另一个表或放置外键?” )这是一个Cloud Function,它将更新所有具有其内容的(“ task”)文档DocumentReference
包含在“用户”文档的专用数组字段taskRefs
中。数组成员为documentation 参考。
exports.updateUser = functions.firestore
.document('users/{userId}')
.onUpdate((change, context) => {
const newValue = change.after.data();
const name = newValue.name;
const taskRefs = newValue.taskRefs;
const promises = taskRefs.map(ref => { ref.update({ name: name, foo: "bar" }) });
return Promise.all(promises);
});
您很可能会从前端在“用户”文档中设置此taskRefs
字段的值。 JS SDK遵循以下原则:
const db = firebase.firestore();
db.collection('users').doc('...').set({
field1: "foo",
field2: "bar",
taskRefs: [ // < = This is an Array of References
db.collection('tasks').doc('....'),
db.collection('tasks').doc('....')]
});