Firebase 查询的优化。通过id获取数据
Optimalization of firebase query. Getting data by ids
我是 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 的当前用户获取商品?我的意思是,是否存在获取 ID 在参数数组中的 only 商品的方法? 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 等,但每个都是针对列表的。我完全糊涂了。有没有人可以帮助我?也许我在应用程序结构的设计中犯了错误。如果是这样,我要求澄清。
是的,您可以在 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());
});
这将 return 仅与 waresID
或 userId
相关的数据
注意:这是 javascript 代码,希望对您有用。
您可以做两件事。我不相信 Firebase 允许您一次查询多个等于值。但是,您可以遍历 "ids" 的数组并直接查询每个数组。
我假设您已经查询了 "waresIds"
并且您已将这些 ID 存储在名为 idArray:
的数组中
for id in idArray {
database.ref('warehouse/wares').orderByChild('id').equalTo(id).once('value').then((snapshot) => {
console.log(snapshot.val());
})
}
为了有效地使用上述查询,您必须 index your data on id.
您的第二个选择是 use .childChanged
在初始获取后仅获取更新的数据。这应该会大大减少您需要下载的数据量。
因为您要将 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;
});
});
我是 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 的当前用户获取商品?我的意思是,是否存在获取 ID 在参数数组中的 only 商品的方法? 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 等,但每个都是针对列表的。我完全糊涂了。有没有人可以帮助我?也许我在应用程序结构的设计中犯了错误。如果是这样,我要求澄清。
是的,您可以在 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());
});
这将 return 仅与 waresID
或 userId
注意:这是 javascript 代码,希望对您有用。
您可以做两件事。我不相信 Firebase 允许您一次查询多个等于值。但是,您可以遍历 "ids" 的数组并直接查询每个数组。
我假设您已经查询了 "waresIds"
并且您已将这些 ID 存储在名为 idArray:
for id in idArray {
database.ref('warehouse/wares').orderByChild('id').equalTo(id).once('value').then((snapshot) => {
console.log(snapshot.val());
})
}
为了有效地使用上述查询,您必须 index your data on id.
您的第二个选择是 use .childChanged
在初始获取后仅获取更新的数据。这应该会大大减少您需要下载的数据量。
因为您要将 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;
});
});