Firebase - 深度查询 orderByChild 与 equalTo
Firebase - Deep Query orderByChild with equalTo
我试图通过其中的成员抓住每个项目 -- 我已经创建了一个示例数据结构,尽管实际结构要大得多(因为重组数据库很困难)。
这是我的查询:
var ref = new Firebase(FBURL + '/chat/meta/project');
var email = 'kerry@email.com';
ref
.orderByChild("email")
.equalTo(email)
.on("child_added", function(snapshot) {
console.log(snapshot.val());
}
);
重要的是要注意,如果我删除 .equalTo(email)
它 return 所有 "projects",而它应该只有 return 2 个。
这是 Firebase 中的数据:
{
"chat" : {
"meta" : {
"project" : {
"-KAgjWOxjk80HIbNr68M" : {
"name" : "Gman Branding",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:33:25.170Z",
"member" : {
"-KAgkD-2GVESwNwKP3fA" : {
"email" : "abc@gman.com"
},
"-KAgkP3M4nug9Bjn-vY6" : {
"email" : "def@gman.com"
},
"-KAgkP3OF0sUgc9x9p37" : {
"email" : "ghi@gman.com"
},
"-KAgkaMyEOiXft6o-HbO" : {
"email" : "kerry@email.com"
}
}
},
"-KAgl9xlPDU5T4072FgE" : {
"-KAglqH9pxkhgC84_kAl" : {
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "billing test 1",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-02-25T23:18:55.626Z",
"dateNotifyUnread" : "2016-01-25T23:23:55.626Z",
"member" : {
"-KAglNsswyk66qUZNrTU" : {
"email" : "kerry@email.com"
}
}
},
"-KAgltmLk2oOYhEDfwRL" : {
"-KAgm1Jt5q53gzLm1GIh" : {
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z",
"member" : {
"-KAgm1Jvss9AMZa1qDb7" : {
"email" : "joe@yudog.com"
}
}
},
"-KAgluTcE_2dv00XDm1L" : {
"-KAgm6ENmkpDiDG2lqZ4" : {
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"-KAgmBptbeInutRzNinm" : {
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z",
"member" : {
"-KAgm6EQcvQg3oP-OnIF" : {
"email" : "joe@yudog.com"
},
"-KAgmBpwoxPYGXS9fLZ9" : {
"email" : "joe@yudog.com"
}
}
}
}
}
}
}
我查看了 SO 上的 8-10 个其他链接,但没有找到任何解决此问题的链接。
解决方案是创建符合您需求的数据结构。在这种情况下,您希望根据用户的电子邮件地址查找用户的项目。所以我们将 添加 一个包含此映射的节点:
"projects_by_email": {
"kerry@email,com": {
"-KAgjWOxjk80HIbNr68M": true,
"-KAgl9xlPDU5T4072FgE": true
},
"abc@gman,com": {
"-KAgjWOxjk80HIbNr68M": true
}
...
}
这称为对数据进行反规范化,尽管我经常将它们视为倒排索引。我可能会通过 uid 保留项目,但结构是相同的。
使用这样的结构,您可以通过简单的直接查找获得电子邮件的项目列表:
var ref = new Firebase(FBURL);
var email = 'kerry@email.com';
ref.child('projects_by_email')
.child(email)
.on("child_added", function(snapshot) {
console.log(snapshot.key());
}
);
或者如果您还想 "join" 项目本身:
var ref = new Firebase(FBURL);
var email = 'kerry@email.com';
ref.child('projects_by_email')
.child(email)
.on("child_added", function(snapshot) {
ref.child('project').child(snapshot.key()).once('value', function(projectSnapshot) {
console.log(projectSnapshot.val());
});
}
);
这种类型的反规范化是 NoSQL 数据建模的正常部分。重复可能会让人觉得很浪费,但这正是 NoSQL 解决方案扩展如此之好的部分原因:上面代码的 none 要求数据库考虑所有 projects/all 用户。都是直接访问正确的节点,扩展性非常好。所以我们牺牲存储 space 来获得改进 performance/scalability;典型的 space 与时间的权衡。
我试图通过其中的成员抓住每个项目 -- 我已经创建了一个示例数据结构,尽管实际结构要大得多(因为重组数据库很困难)。
这是我的查询:
var ref = new Firebase(FBURL + '/chat/meta/project');
var email = 'kerry@email.com';
ref
.orderByChild("email")
.equalTo(email)
.on("child_added", function(snapshot) {
console.log(snapshot.val());
}
);
重要的是要注意,如果我删除 .equalTo(email)
它 return 所有 "projects",而它应该只有 return 2 个。
这是 Firebase 中的数据:
{
"chat" : {
"meta" : {
"project" : {
"-KAgjWOxjk80HIbNr68M" : {
"name" : "Gman Branding",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:33:25.170Z",
"member" : {
"-KAgkD-2GVESwNwKP3fA" : {
"email" : "abc@gman.com"
},
"-KAgkP3M4nug9Bjn-vY6" : {
"email" : "def@gman.com"
},
"-KAgkP3OF0sUgc9x9p37" : {
"email" : "ghi@gman.com"
},
"-KAgkaMyEOiXft6o-HbO" : {
"email" : "kerry@email.com"
}
}
},
"-KAgl9xlPDU5T4072FgE" : {
"-KAglqH9pxkhgC84_kAl" : {
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "billing test 1",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-02-25T23:18:55.626Z",
"dateNotifyUnread" : "2016-01-25T23:23:55.626Z",
"member" : {
"-KAglNsswyk66qUZNrTU" : {
"email" : "kerry@email.com"
}
}
},
"-KAgltmLk2oOYhEDfwRL" : {
"-KAgm1Jt5q53gzLm1GIh" : {
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "YuDog",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z",
"member" : {
"-KAgm1Jvss9AMZa1qDb7" : {
"email" : "joe@yudog.com"
}
}
},
"-KAgluTcE_2dv00XDm1L" : {
"-KAgm6ENmkpDiDG2lqZ4" : {
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"-KAgmBptbeInutRzNinm" : {
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z"
},
"name" : "YuDog Landing Page",
"url" : "http://localhost:3000/project/abc123fasd123cc/...",
"date" : "2015-10-10T21:41:31.172Z",
"member" : {
"-KAgm6EQcvQg3oP-OnIF" : {
"email" : "joe@yudog.com"
},
"-KAgmBpwoxPYGXS9fLZ9" : {
"email" : "joe@yudog.com"
}
}
}
}
}
}
}
我查看了 SO 上的 8-10 个其他链接,但没有找到任何解决此问题的链接。
解决方案是创建符合您需求的数据结构。在这种情况下,您希望根据用户的电子邮件地址查找用户的项目。所以我们将 添加 一个包含此映射的节点:
"projects_by_email": {
"kerry@email,com": {
"-KAgjWOxjk80HIbNr68M": true,
"-KAgl9xlPDU5T4072FgE": true
},
"abc@gman,com": {
"-KAgjWOxjk80HIbNr68M": true
}
...
}
这称为对数据进行反规范化,尽管我经常将它们视为倒排索引。我可能会通过 uid 保留项目,但结构是相同的。
使用这样的结构,您可以通过简单的直接查找获得电子邮件的项目列表:
var ref = new Firebase(FBURL);
var email = 'kerry@email.com';
ref.child('projects_by_email')
.child(email)
.on("child_added", function(snapshot) {
console.log(snapshot.key());
}
);
或者如果您还想 "join" 项目本身:
var ref = new Firebase(FBURL);
var email = 'kerry@email.com';
ref.child('projects_by_email')
.child(email)
.on("child_added", function(snapshot) {
ref.child('project').child(snapshot.key()).once('value', function(projectSnapshot) {
console.log(projectSnapshot.val());
});
}
);
这种类型的反规范化是 NoSQL 数据建模的正常部分。重复可能会让人觉得很浪费,但这正是 NoSQL 解决方案扩展如此之好的部分原因:上面代码的 none 要求数据库考虑所有 projects/all 用户。都是直接访问正确的节点,扩展性非常好。所以我们牺牲存储 space 来获得改进 performance/scalability;典型的 space 与时间的权衡。