firebase查询的优化。按ID

时间:2018-01-24 11:39:09

标签: javascript firebase firebase-realtime-database angularfire ngrx

我是Firebase的新手。我想创建一个应用(使用Angular和AngularFire库),它显示了一些商品的当前价格。我按以下格式列出了Firebase实时数据库中所有可用的商品:

"warehouse": {
   "wares": {
      "id1": {
         "id": "id1",
         "name": "name1",
         "price": "0.99"
      },
      "id2": {
         "id": "id2",
         "name": "name2",
         "price": "15.00"
      },
      ... //much more stuff
   }
}

我在我的应用中使用ngrx,因此我认为我可以加载所有商品以将存储为不列出的对象,因为规范化状态树。我希望以这种方式存储加载商品:

this.db.object('warehouse/wares').valueChanges();

问题是商品的价格会每5分钟刷新一次。数量og wares是巨大的(约3000项)所以一个响应将是重量约700kB。我知道我会以这种方式在短时间内超过限制下载的数据。

我想限制加载数据为用户进行交互,因此每个用户都可以选择商品。我将以下列方式存储这些选择:

"users": {
   "user1": {
      "id": "user1",
      "wares": {
          "id1": {
             "order": 1
          },
          "id27": {
             "order": 2
          },
          "id533": {
             "order": 3
          }
      },
      "waresIds": ["id1", "id27", "id533"]
   }
}

我的问题是:

有没有办法根据waresIds的当前用户获取商品?我的意思是,是否存在获得商品的方法,其ids在参数数组中? F.E.

"wares": {
   "id1": {
      "id": "id1",
      "name": "name1",
      "price": "0.99"
   },
   "id27": {
      "id": "id27",
      "name": "name27",
      "price": "0.19"
   },
   "id533": {
      "id": "id533",
      "name": "name533",
      "price": "1.19"
   }
}

用于查询:

this.db.object('warehouse/wares').contains(["id1", "id27", "id533"]).valueChanges();

我看到了Angular Fire中的查询限制,例如equalTo等等,但每个都是列表。我完全糊涂了。有没有人可以帮助我?也许我在应用程序结构的设计中犯了错误。如果是的话,我要求澄清。

3 个答案:

答案 0 :(得分:2)

你可以做两件事。我不相信Firebase允许您一次查询多个等于的值。然而,您可以遍历" ID"并直接查询每一个。

我假设您已经查询了Table2,并且您已将这些ID存储在名为idArray的数组中:

ParseDataFromManyTables

为了有效地使用上述查询,您必须index your data on id

您的第二个选项是use "waresIds",以便在初次获取后仅获取更新的数据。这应该会大幅减少您需要下载的数据量。

答案 1 :(得分:1)

是的,你可以在firebase中获得你想要的数据,

See official Firebase documents about filtering

您需要获取每个waresID

        var waresID = // logic to get waresID 
        var userId  = // logic to get userId
        var ref = firebase.database().ref("wares/" + userId).child(waresID);
        ref.once("value")
            .then(function(snapshot) {
               console.log(snapshot.val());
            });

这将仅返回与waresIDuserId

相关的数据

注意:这是javascript代码,我希望这对您有用。

答案 2 :(得分:1)

因为您正在用户内部保存ID,请尝试这种方式。

wares: Observable<any[]>; 

//inside ngOnInit or function
this.wares = this.db.list('users/currentUserId/wares').snapshotChanges().map(changes => {
  return changes.map(c => {
      const id = c.payload.key; //gets ids under users/wares/ids..
      let wares=[];
      //now get the wares
      this.db.list('warehouse/wares', ref => ref.orderByChild('id').equalTo(id)).valueChanges().subscribe(res=>{
        res.forEach(data=>{
            wares.push(data);
        })
      });
    return wares;
  });
});