我已经为我的新项目从解析服务器转移到了防火墙,但在这个项目中,我开始认为这是个坏主意。
基本上,我正在制作一个应用程序,人们可以在这个应用程序中发布关于他们镇上正在举行的音乐会的信息。
我的第一个挑战是过滤事件,因此用户只能在自己的城镇中获取事件。我是通过整理城市后的数据来做到这一点的:
{
concerts: {
"New york": {
...,
...
},
"Chicago": {
...,
...
}
}
}然后我想我需要另一个过滤器的类型的音乐会,例如摇滚,流行,等等。所以我想我做了另一个重组。但是,可能还需要5-10个过滤器,而且很难以一种很好的方式构造数据库。
I考虑了多个查询,但这是不允许的:
firebase.database().ref("concerts")
.orderByChild("type").equalTo("rock")
.orderByChild("length").equalTo("2")
.orderByChild("artist").equalTo("beatles")--我考虑从服务器获取所有,然后在客户机中过滤结果。不过,我觉得有两个问题:
--我考虑将过滤器组合起来创建查询键,就像这个这,但是有了超过10个过滤器,就会变得非常复杂。
有解决这个问题的办法吗?还是我应该忘记这个用例的防火墙?
提前感谢
发布于 2017-03-09 17:38:49
可以在Firebase中构建极其复杂的查询。数据需要存储在便于查询的结构中,最重要的是,不要害怕重复的数据。
例如,让我们假设我们有一个应用程序,使用户能够选择一个特定的年份和月份,一个特定的城市,和一个特定类型的音乐会。
有三个参数
year_month城市体裁
UI首先询问用户选择一个城市
Austin然后UI要求选择一年和一个月。
201704然后是一种类型
Rock您的Firebase结构如下
concerts
concert_00
city: Memphis
year_month: 201706
genre: Country
city_date_genre: Memphis_201606_Country
concert_01
city: Austin
year_month: 201704
genre: Rock
city_date_genre: Austin_201704_Rock
concert_02
city: Seattle
year_month: 201705
genre: Disco
city_date_genre: Seattle_201705_Disco您的UI已经对用户进行查询信息的轮询,并据此构建一个查询字符串。
Austin_201704_Rock然后查询该字符串的“city_date_genre”节点,您就有了数据。
如果用户想知道2017年4月在奥斯汀举行的所有音乐会怎么办?
queryStartingAt("Austin_201704").queryEndingAt("Austin_201704")通过添加另一个查询节点并更改数据的顺序,您可以轻松地展开这方面的工作。
concerts
concert_00
city: Memphis
year_month: 201706
genre: Country
city_date_genre: Memphis_201606_Country
city_genre_date: Memphis_Country_201606根据用户选择数据的顺序,您可以查询相关节点。
添加额外的节点是一小部分数据,允许对所需数据进行非常开放的查询。
发布于 2021-06-14 08:39:20
我看到这是一篇老文章,但我想借此机会向其他遇到类似Firebase问题的人介绍一下AceBase,后者是Firebase实时数据库的一个免费和开放源码的替代方案。在Firebase中缺少适当的查询和索引选项是构建AceBase的原因之一。使用AceBase可以像这样查询数据:
const snapshots = await db.ref('concerts')
.query()
.filter('city', '==', 'New York')
.filter('date', 'between', [today, nextWeek]) // today & nextWeek being Dates
.filter('genre', 'in', ['rock', 'blues', 'country'])
.get();由于AceBase支持索引,在查询字段中添加一个或多个索引将使这些查询运行得非常快,即使有数百万条记录。它支持简单索引,但也支持FullText和Geo索引,因此您还可以使用位置和关键字查询数据:
.filter('location', 'geo:nearby', { lat: 40.730610, long: -73.935242, radius: 10000 }) // New York center with 10km radius
.filter('title', 'fulltext:contains', '"John Mayer" OR "Kenny Wayne Shepherd"')如果要限制结果以允许分页,只需添加跳过和限制:.skip(80).limit(20)
此外,如果希望使查询提供实时结果,那么任何新添加的音乐会都会立即通知应用程序--只需添加事件侦听器就可以将其升级为实时查询:
const results = await db.ref('concerts')
.filter('location', 'geo:nearby', { lat: 40.730610, long: -73.935242, radius: 10000 })
.on('add', addConcert)
.on('remove', removeConcert)
.get();
function addConcert(match) {
results.push(match.snapshot);
updateUI();
}
function removeConcert(match) {
const index = results.findIndex(r => r.ref.path === match.ref.path);
results.splice(index, 1);
updateUI();
}如果您想了解更多关于AceBase的信息,请在npm:https://www.npmjs.com/package/acebase上查看。AceBase是免费的,它的全部源代码都可以在GitHub上使用。玩得开心!
https://stackoverflow.com/questions/42672790
复制相似问题