我在node.js上使用firebase。
我给定的结构应如下所示:
{
...
batch-1:
id-1(suppose):
name:...
phone:...
id-2:
...
id-3:
...
batch-2:
...
batch-3:
...
...
batch-n:
...
}
在这样的体系结构中,如何通过其标识符获取id-1对象? 数据库是否必须遍历所有批次? 有更好的解决方案吗? 主要任务:创建包含许多对象的批处理,这些对象将具有SHORT和UNIQUE标识符,并以此标识符最佳地接收数据
答案 0 :(得分:0)
要搜索作为未知ID列表的子代的特定ID,您需要使用orderByChild()
。在您的用例中,您正在批次ID列表中寻找特定的ID。如果您在此列表上使用了orderByChild()
,则即使每个批次ID都没有您想要的ID,您也会获得结果。这是因为结果中甚至包括了null
(不存在)值(并在开始时对其进行了排序)。要获取所需ID的数据,您将获取查询的最后结果的数据(如果存在)为sorted to the end of the list。请注意,如果所需的ID不存在,则最后一个结果(如果有任何结果)将具有null
值。要仅返回查询的最后结果,可以使用limitToLast(1)
。
将所有内容放在一起,给出以下代码:
let idToFind = "unique-id-1";
let batchesRef = firebase.database().ref(); // parent key of "batch-1", "batch-2", etc.
// assumed to be the database root here
batchesRef.orderByChild(idToFind).limitToLast(1).once('value')
.then((querySnapshot) => {
if (!querySnapshot.numChildren()) { // handle rare no-results case
throw new Error('expected at least one result');
}
let dataSnapshot;
querySnapshot.forEach((snap) => dataSnapshot = snap); // get the snapshot we want out of the query's results list
if (!dataSnapshot.exists()) { // value may be null, meaning idToFind doesn't exist
throw new Error(`Entry ${idToFind} not found.`);
}
// do what you want with dataSnapshot
console.log(`Entry ${idToFind}'s data is:`, dataSnapshot.val());
})
.catch((error) => {
console.log("Unexpected error:", error);
})
对于小型数据集,上面的代码可以正常工作。但是,如果批次列表开始变得越来越大,您可能希望建立一个索引,将特定的ID映射到包含该ID的批次ID。
答案 1 :(得分:0)
这是我的方法,它允许您按 id
搜索或按键值搜索,例如 email
uniqueemail
// gets primary key
const getSnapshotValKey = snapshot => (Object.keys(snapshot).length > 0 ? Object.keys(snapshot)[0] : null)
const getUser = async ({ id, key, value }) => {
let user = null
const ref = id ? '/users/' + id : 'users'
const userRef = admin.database().ref(ref)
const valueRef = id ? userRef : await userRef.orderByChild(key).equalTo(value)
const snapshot = await valueRef.once('value')
const val = snapshot.val()
if (val) {
const key = id || getSnapshotValKey(val)
user = {
id: key,
...(id ? val : val[key]),
}
}
return user
}