我有一个带有用户的Firebase Web实时数据库,每个用户都有一个jobs
属性,其值是一个对象:
{
userid1:
jobs:
guid1: {},
guid2: {},
userid2:
jobs:
guid1: {},
guid2: {},
}
我想查询以获取最多工作的n个用户。是否可以使用给定用户在其jobs
属性中拥有的值数来对用户进行排序的排序技巧?
我特别不想存储每个用户拥有的作业数量的整数,因为我需要更新用户的jobs
属性,作为原子更新的一部分,原子更新同时并原子地更新其他用户属性,而且我不认为交易(例如递增/递减计数器)可以成为这些原子交易的一部分。
这是我正在执行的原子更新的示例。注意当我运行以下更新时,我没有正在内存中修改的用户:
firebase.database().ref('/').update({
[`/users/${user.guid}/pizza`]: true,
[`/users/${user.guid}/jobs/${job.guid}/scheduled`]: true,
})
任何有关可用于此数据的模式的建议,将不胜感激!
答案 0 :(得分:2)
实时数据库事务运行在JSON树中的单个节点上,因此很难将原子更新中的jobCounter
节点更新集成到多个节点(即/users/${user.guid}/pizza
和/users/${user.guid}/jobs/${job.guid}/scheduled
)。我们将需要在/users/${user.guid}
级进行更新并计算计数器值,等等。
一种更简单的方法是,每当jobCounter
节点之一发生变化(这意味着计数器发生变化)时,都可以使用Cloud Function更新用户的jobs
节点。换句话说,如果添加或删除了新的作业节点,则更新计数器。如果仅修改现有节点,则不会更新计数器,因为作业数量没有变化。
exports.updateJobsCounter = functions.database.ref('/users/{userId}/jobs')
.onWrite((change, context) => {
if (!change.after.exists()) {
//This is the case when no more jobs exist for this user
const userJobsCounterRef = change.before.ref.parent.child('jobsCounter');
return userJobsCounterRef.transaction(() => {
return 0;
});
} else {
if (!change.before.val()) {
//This is the case when the first job is created
const userJobsCounterRef = change.before.ref.parent.child('jobsCounter');
return userJobsCounterRef.transaction(() => {
return 1;
});
} else {
const valObjBefore = change.before.val();
const valObjAfter = change.after.val();
const nbrJobsBefore = Object.keys(valObjBefore).length;
const nbrJobsAfter = Object.keys(valObjAfter).length;
if (nbrJobsBefore !== nbrJobsAfter) {
//We update the jobsCounter node
const userJobsCounterRef = change.after.ref.parent.child('jobsCounter');
return userJobsCounterRef.transaction(() => {
return nbrJobsAfter;
});
} else {
//No need to update the jobsCounter node
return null;
}
}
}
});