如何通过Firebase Realtime Database孙辈键查询对应祖父级对象
问题原因
你之前的查询返回空,是因为orderByChild('sensors')指向的是sensors这个整体对象,而Firebase的equalTo仅支持匹配字符串、数字、布尔这类基础类型值,无法直接判断对象是否包含某个键,因此匹配永远失败。
解决方案
方案1:使用路径查询(性能最优,优先选择)
直接把要匹配的传感器ID拼接到查询路径中,匹配对应键的值为true即可:
const sensor_id = "-LNVBiM1SGoAFvlMfi1V"; db.ref('/orders') // 指定查询的子级路径为sensors下对应传感器ID的键 .orderByChild(`sensors/${sensor_id}`) // 匹配该键的值为true(和你数据库中的存储结构一致) .equalTo(true) .once('value', snapshot => { // snapshot即为所有包含该传感器的orders对象 console.log(snapshot.val()); });
索引配置
为了保证查询性能,需要在Firebase Realtime Database的安全规则中为对应路径添加索引。如果传感器ID固定且数量较少,可以直接预定义索引:
{ "rules": { "orders": { ".indexOn": ["sensors/-LNVBiM1SGoAFvlMfi1V"] // 多个传感器ID直接追加到数组中即可 } } }
方案2:客户端过滤(仅适用于数据量小的场景)
如果传感器ID是动态生成的,无法提前预定义所有索引,可以先拉取全量orders数据,在客户端遍历过滤:
const sensor_id = "-LNVBiM1SGoAFvlMfi1V"; db.ref('/orders').once('value', snapshot => { const matchedOrders = []; snapshot.forEach(orderSnap => { const orderData = orderSnap.val(); // 判断sensors对象下是否存在对应传感器ID的键 if (orderData.sensors && orderData.sensors.hasOwnProperty(sensor_id)) { matchedOrders.push(orderData); } }); console.log(matchedOrders); });
该方案的缺点是orders数据量大时会占用大量带宽,查询性能很低,仅适合测试或数据量极小的场景。
参考数据库结构


内容的提问来源于stack exchange,提问作者Yoann Hercouet
相关产品推荐
相关产品推荐

