Firebase - 如何编写多个 orderByChild 来提取数据?
Firebase - How do I write multiple orderByChild for extracting data?
我希望获取两个字段等于我传入的字段的数据。
这是我的代码示例:
this.refApp
.orderByChild('userUid')
.startAt(uid).endAt(uid)
.orderByChild('jobId')
.startAt(jobId).endAt(jobId)
.on('value', (snap) => {
//This currently doesn't get returned.
});
在上面的示例中,我没有遇到任何编译器错误,而且代码看起来没问题。
但是,我对数据进行了硬编码,以便它 return 一个 uid 和 jobid 等于的对象。
我可以让它为一个 orderByChild 工作,但是当我像上面那样做两个时,它似乎没有做任何事情。
您只能使用一种订购方式。
要查询更多,您需要重新考虑您的数据结构。您当前的结构可能如下所示:
{
"key": {
"id_1": {
"userUid": "user_1",
"jobId": "job_1"
},
"id_2": {
"userUid": "user_1",
"jobId": "job_2"
},
"id_3": {
"userUid": "user_2",
"jobId": "job_3"
}
}
}
使用这种结构,您只能索引一个子键。
现在考虑这个结构:
{
"key": {
"user_1": {
"id_1": {
"jobId": "job_1",
"userUid": "user_1"
},
"id_2": {
"jobId": "job_2",
"userUid": "user_1"
}
}
"user_2": {
"id_3": {
"jobId": "job_3",
"userUid": "user_2"
}
}
}
}
此结构在 uid
上显式创建索引。所以现在如果你想得到用户的所有工作,你可以写这个查询:
var ref = new Firebase('<my-firebase-app>');
var uid = 'user_1';
var userRef = ref.child('key').child(uid);
var query = userRef.orderByChild('jobId');
query.on('value', (snap) => console.log(snap.val());
不支持。
根据您需要在实体上 运行 的查询类型,您要么必须像 @david-east 建议的那样按用户存储作业,要么添加一个 属性 将两者结合起来属性:
{
jobId: 'J123',
userId: 'provider:123',
jobIdUserIdIndex: 'J123/provider:12345',
[...]
}
但通常情况下,没有办法允许您需要的所有查询。您要么必须在客户端过滤对象,要么复制数据以创建不同的数据视图;您将在 /jobs/$jobId
、/users/$userId/jobs/$jobId
和 /pendingJobs/$jobId
.
处保存作业数据
我发现将 orderBy* 方法仅用于排序实体并将数据复制到它们的 select 个子集会更容易。
我希望 Firebase 支持组合多个属性的索引,但现在您需要自己构建这些索引。但是,具有不同的视图允许对它们应用不同的安全规则:例如只有一个用户应该有权访问 /users/$userId/jobs/
,只有管理员应该有权访问 /jobs/$jobId
。
另一种在 Firebase 中实现多重 orderByChild
的方法是创建一个 orderKey。
假设你的基地里有这个:
{
userId: {
firstName: 'Jon',
lastName: 'Snow',
birthYear: 283
}
}
而你要查询:userRef.orderByChild('firstName').equalTo('Jon').orderByChild('lastName').equalTo('Snow')
您需要像这样为您的用户创建密钥:
{
userId: {
firstName: 'Snow',
lastName: 'Jon',
birthYear: 283,
orderName: 'JonSnow'
}
}
所以你可以这样查询:userRef.orderByChild('orderName').equalTo('JonSnow')
这也适用于 startAt
和 endAt
如果你想查询在一个年份范围内出生的所有 Snow。您首先创建密钥:
{
userId: {
firstName: 'Snow',
lastName: 'Jon',
birthYear: 283,
orderNameYear: 'Snow283'
}
}
所以可以查询:userRef.orderByChild('orderNameYear').startAt('Snow280').endAt('Snow285')
这将 return 出生在 280 到 285 之间的所有 Snow。
我希望获取两个字段等于我传入的字段的数据。
这是我的代码示例:
this.refApp
.orderByChild('userUid')
.startAt(uid).endAt(uid)
.orderByChild('jobId')
.startAt(jobId).endAt(jobId)
.on('value', (snap) => {
//This currently doesn't get returned.
});
在上面的示例中,我没有遇到任何编译器错误,而且代码看起来没问题。 但是,我对数据进行了硬编码,以便它 return 一个 uid 和 jobid 等于的对象。
我可以让它为一个 orderByChild 工作,但是当我像上面那样做两个时,它似乎没有做任何事情。
您只能使用一种订购方式。
要查询更多,您需要重新考虑您的数据结构。您当前的结构可能如下所示:
{
"key": {
"id_1": {
"userUid": "user_1",
"jobId": "job_1"
},
"id_2": {
"userUid": "user_1",
"jobId": "job_2"
},
"id_3": {
"userUid": "user_2",
"jobId": "job_3"
}
}
}
使用这种结构,您只能索引一个子键。
现在考虑这个结构:
{
"key": {
"user_1": {
"id_1": {
"jobId": "job_1",
"userUid": "user_1"
},
"id_2": {
"jobId": "job_2",
"userUid": "user_1"
}
}
"user_2": {
"id_3": {
"jobId": "job_3",
"userUid": "user_2"
}
}
}
}
此结构在 uid
上显式创建索引。所以现在如果你想得到用户的所有工作,你可以写这个查询:
var ref = new Firebase('<my-firebase-app>');
var uid = 'user_1';
var userRef = ref.child('key').child(uid);
var query = userRef.orderByChild('jobId');
query.on('value', (snap) => console.log(snap.val());
不支持。
根据您需要在实体上 运行 的查询类型,您要么必须像 @david-east 建议的那样按用户存储作业,要么添加一个 属性 将两者结合起来属性:
{
jobId: 'J123',
userId: 'provider:123',
jobIdUserIdIndex: 'J123/provider:12345',
[...]
}
但通常情况下,没有办法允许您需要的所有查询。您要么必须在客户端过滤对象,要么复制数据以创建不同的数据视图;您将在 /jobs/$jobId
、/users/$userId/jobs/$jobId
和 /pendingJobs/$jobId
.
我发现将 orderBy* 方法仅用于排序实体并将数据复制到它们的 select 个子集会更容易。
我希望 Firebase 支持组合多个属性的索引,但现在您需要自己构建这些索引。但是,具有不同的视图允许对它们应用不同的安全规则:例如只有一个用户应该有权访问 /users/$userId/jobs/
,只有管理员应该有权访问 /jobs/$jobId
。
另一种在 Firebase 中实现多重 orderByChild
的方法是创建一个 orderKey。
假设你的基地里有这个:
{
userId: {
firstName: 'Jon',
lastName: 'Snow',
birthYear: 283
}
}
而你要查询:userRef.orderByChild('firstName').equalTo('Jon').orderByChild('lastName').equalTo('Snow')
您需要像这样为您的用户创建密钥:
{
userId: {
firstName: 'Snow',
lastName: 'Jon',
birthYear: 283,
orderName: 'JonSnow'
}
}
所以你可以这样查询:userRef.orderByChild('orderName').equalTo('JonSnow')
这也适用于 startAt
和 endAt
如果你想查询在一个年份范围内出生的所有 Snow。您首先创建密钥:
{
userId: {
firstName: 'Snow',
lastName: 'Jon',
birthYear: 283,
orderNameYear: 'Snow283'
}
}
所以可以查询:userRef.orderByChild('orderNameYear').startAt('Snow280').endAt('Snow285')
这将 return 出生在 280 到 285 之间的所有 Snow。