如何使用查询或特定路径从Firebase实时数据库高效查询
我们很少对Firebase实时数据库进行财产修改(“价格”),其结构如下:如何使用查询或特定路径从Firebase实时数据库高效查询,firebase,firebase-realtime-database,Firebase,Firebase Realtime Database,我们很少对Firebase实时数据库进行财产修改(“价格”),其结构如下: ../currencies/<currency>/value/ "price":343 这些货币的价格很少变动 由于这种结构,当数据发生变化时,我们的服务器端需要对所有货币的数据进行修改和非规范化(我们可以有十种货币) 正因为如此,我们在leaf中添加了更多在所有货币上都相同的属性 我觉得这是多余的,比如: ../currencies/USD/value/ "price":3
../currencies/<currency>/value/
"price":343
这些货币的价格很少变动由于这种结构,当数据发生变化时,我们的服务器端需要对所有货币的数据进行修改和非规范化(我们可以有十种货币) 正因为如此,我们在leaf中添加了更多在所有货币上都相同的属性 我觉得这是多余的,比如:
../currencies/USD/value/
"price":343
"currency-source":"fx" . //this property will be copied to all
因为客户机只侦听一条路径,而且它也需要这些数据,所以使用VAL
相反,如果在路径上保存了这个,也许我们可以使用一些查询,每个客户都可以根据属性名称选择其货币
诸如此类:
../currencies/value/
"USD_price":343
"EUR_price":343
...
关于设计的想法?如果听起来更好的话,如何使用Firebase实时数据库查询实现呢?我不知道您在应用程序中使用哪种语言(哪种客户端SDK),但这里有一个使用JavaScript SDK的解决方案 假设您有一个Relatime数据库结构,如下所示
"parentnode" : {
"currencies" : {
"EUR" : {
"value" : {
"price" : 201
}
},
"USD" : {
"value" : {
"price" : 343
}
},
"value" : {
"EUR_price" : 201,
"USD_price" : 343,
"currency-source" : "fx"
}
}
}
在parentnode
下有一个currences
节点,该节点对应于您问题中的示例
如果您想收听/currences//value
,请执行以下操作:
var db = firebase.database();
var currency = 'EUR';
var ref = db.ref().child('parentnode/currencies/' + currency);
ref.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var db = firebase.database();
var currency = 'EUR';
var ref = db.ref().child('parentnode/currencies/value');
ref.on('value', function(snapshot) {
var data = snapshot.val();
var price = data[currency + '_price'];
var source = data['currency-source'];
console.log(price);
console.log(source);
});
var currency = 'EUR';
var ref2 = db
.ref()
.child('parentnode/currencies/value/' + currency + '_price');
ref2.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var ref3 = db.ref().child('parentnode/currencies/value/currency-source');
ref3.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var currency = 'EUR';
var ref5 = db.ref().child('parentnode/currencies/value/' + currency + '_price');
var ref6 = db.ref().child('parentnode/currencies/value/currency-source');
ref5
.once('value')
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
return ref6.once('value');
})
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
});
如果您想收听/currences/value/\u price
并获取价格
和货币源
值,请执行以下操作:
var db = firebase.database();
var currency = 'EUR';
var ref = db.ref().child('parentnode/currencies/' + currency);
ref.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var db = firebase.database();
var currency = 'EUR';
var ref = db.ref().child('parentnode/currencies/value');
ref.on('value', function(snapshot) {
var data = snapshot.val();
var price = data[currency + '_price'];
var source = data['currency-source'];
console.log(price);
console.log(source);
});
var currency = 'EUR';
var ref2 = db
.ref()
.child('parentnode/currencies/value/' + currency + '_price');
ref2.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var ref3 = db.ref().child('parentnode/currencies/value/currency-source');
ref3.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var currency = 'EUR';
var ref5 = db.ref().child('parentnode/currencies/value/' + currency + '_price');
var ref6 = db.ref().child('parentnode/currencies/value/currency-source');
ref5
.once('value')
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
return ref6.once('value');
})
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
});
正如您在评论中提到的,第二种方法意味着“我们将下载
/currences/value/
下的所有数据页”
我可以想出另外两种可能的方法。选择一个而不是另一个实际上取决于您的功能需求,即您在前端如何处理这些值
1/设置两个侦听器
其思想是为'parentnode/currencies/value/'+currency+'\u price'
设置一个侦听器,并为'parentnode/currencies/value/currency source'
设置一个侦听器,如下所示:
var db = firebase.database();
var currency = 'EUR';
var ref = db.ref().child('parentnode/currencies/' + currency);
ref.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var db = firebase.database();
var currency = 'EUR';
var ref = db.ref().child('parentnode/currencies/value');
ref.on('value', function(snapshot) {
var data = snapshot.val();
var price = data[currency + '_price'];
var source = data['currency-source'];
console.log(price);
console.log(source);
});
var currency = 'EUR';
var ref2 = db
.ref()
.child('parentnode/currencies/value/' + currency + '_price');
ref2.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var ref3 = db.ref().child('parentnode/currencies/value/currency-source');
ref3.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var currency = 'EUR';
var ref5 = db.ref().child('parentnode/currencies/value/' + currency + '_price');
var ref6 = db.ref().child('parentnode/currencies/value/currency-source');
ref5
.once('value')
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
return ref6.once('value');
})
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
});
2/查询侦听器中的货币源
值
使用第二种方法,在'parentnode/currences/value/'+currency+'\u price'
的侦听器中,我们使用以下方法查询数据库以获取货币源的值:
var ref4 = db
.ref()
.child('parentnode/currencies/value/' + currency + '_price');
ref4.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
db.ref()
.child('parentnode/currencies/value/currency-source')
.once('value')
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
});
});
请注意,如果不需要设置侦听器,即希望一次获取数据(例如,通过从按钮触发获取,或在页面加载等…),则应仅使用一次()
方法,然后可以按如下方式链接两个调用:
var db = firebase.database();
var currency = 'EUR';
var ref = db.ref().child('parentnode/currencies/' + currency);
ref.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var db = firebase.database();
var currency = 'EUR';
var ref = db.ref().child('parentnode/currencies/value');
ref.on('value', function(snapshot) {
var data = snapshot.val();
var price = data[currency + '_price'];
var source = data['currency-source'];
console.log(price);
console.log(source);
});
var currency = 'EUR';
var ref2 = db
.ref()
.child('parentnode/currencies/value/' + currency + '_price');
ref2.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var ref3 = db.ref().child('parentnode/currencies/value/currency-source');
ref3.on('value', function(snapshot) {
var data = snapshot.val();
console.log(data);
});
var currency = 'EUR';
var ref5 = db.ref().child('parentnode/currencies/value/' + currency + '_price');
var ref6 = db.ref().child('parentnode/currencies/value/currency-source');
ref5
.once('value')
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
return ref6.once('value');
})
.then(function(dataSnapshot) {
console.log(dataSnapshot.val());
});
这似乎完全可行。与。/currences//value
节点相比,您在收听。/currences//value
节点时是否遇到任何困难?“Firebase数据库查询如何实现”->您正在使用哪些SDK(JS、Android、iOS)?@RenaudTarnec我们没有困难,我只是认为这会使Firebase树模型复杂化,而没有实际价值。我们使用JSSDK“它使我们的firebase树模型复杂化,而没有实际价值”->哪种方法使它复杂化?收听../Currences/value/_价格节点或收听../Currences//value one?你到底在问什么?最佳方法是什么?@RenaudTarnec./currences//value one?->使事情变得复杂(正如我在问题中详述的),因为我们复制了所有属性。我不知道如何在客户端使用./currences/value/_price方法,所以他只会选择玩家选择的货币。如果你能回答这个问题,告诉我你在前端使用哪种语言,我会很高兴的?例如,您使用的是哪种Firebase客户端SDK?谢谢您的回复。第二种方法是可行的。但这意味着我们将下载/currences/value/下的所有数据页,因为var price=data[currency+''u price']将在客户端本地工作。我认为有一种方法可以从firebaseYes中专门查询该密钥。在昨天写了答案之后,我真的想了想:-)我在答案中添加了一些可能的方法。@rayman实际上注意到,在我最初的答案中,我把one()
方法和on()
one方法混在了一起。。。。由于要设置侦听器,您需要使用on()
方法(我已经修改了答案)。如果您只想听一次(例如,通过从按钮触发获取,或在页面加载等…),您应该使用one()
方法。@rayman您好,您有机会看一下更新吗?是的。在所有示例中,您都下载了所有leaf,并进行本地操作。我想知道我是否可以利用firebase query只下载玩家需要的货币价格,而不下载所有的货币,因为我们可以轻松获得100种货币。谢谢