繁体   English   中英

如何使用查询或特定路径从 Firebase 实时数据库中高效查询

[英]How to efficiently query from Firebase Realtime Database using query or specific path

我们很少对 Firebase 实时数据库进行属性修改(“价格”),其结构如下:

../currencies/<currency>/value/
      "price":343

每个登录的玩家都只会收听一种特定的货币。 我们的客户会根据玩家的喜好选择正确的货币路径。

因此,如果播放器设置为货币 USD,则 firebase 客户端将监听此路径

../currencies/USD/value/
      "price":343

这些货币价格不经常变动
由于这种结构,我们的服务器端需要在数据发生变化时将数据修改和非规范化为所有货币(我们可以有十种货币)因此我们向叶子添加了更多在所有货币上都相同的属性

我发现它像:

../currencies/USD/value/
          "price":343
          "currency-source":"fx" . //this property will be copied to all 

currency vals,因为客户端只听一条路径,它也需要这些数据

相反,如果在路径上维护这个,也许我们可以使用一些查询,每个客户都可以根据属性名称选择它的货币?

是这样的:

../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节点下,您有一个currencies节点对应于您问题中的示例

如果你想听/currencies/<currency>/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);
  });

如果您想收听/currencies/value/<currency>_price并获取pricecurrency-source值,您可以执行以下操作:

  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);
  });

正如您在评论中提到的,第二种方法意味着“我们将下载/currencies/value/下的所有数据叶”。

我可以想到另外两种可能的方法。 选择一个而不是另一个实际上取决于您的功能需求,即您在前端如何处理这些值。

1/ 设置两个监听器

这个想法是为'parentnode/currencies/value/' + currency + '_price'设置一个监听器,为'parentnode/currencies/value/currency-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);
  });

2/ 查询监听器内的currency-source

使用第二种方法,在'parentnode/currencies/value/' + currency + '_price'中,我们使用once()方法查询数据库以获取currency-source的值:

  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());
      });
  });

请注意,如果您不需要设置侦听器,即您只想获取一次数据(例如,通过从按钮触发获取,或在页面加载时等),您应该只使用once()方法,然后您可以按如下方式链接这两个调用:

  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());
    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM