Javascript 使用 Firebase 进行数据库式查询
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11587775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Database-style Queries with Firebase
提问by Matt Robertson
Is there a fast way to perform database-style queries with Firebase?
是否有使用 Firebase 执行数据库样式查询的快速方法?
For example:
例如:
Given a firebase reference users
with fields user_id
, name
, and age
, what would be the best way to do a query similar to this:
给定一个users
带有字段user_id
、name
和的 firebase 引用,age
执行与此类似的查询的最佳方法是什么:
SELECT name FROM users WHERE `user_id`=147;
and
和
SELECT COUNT(*) FROM users WHERE age=21;
回答by Michael Lehenbauer
In general, no. Firebase is essentially a "realtime database", constantly streaming updates to you as data changes, so it's more difficult to do general-purpose querying. For now, there are a couple of (admittedly limited) querying primitives that are provided. See the Queries/Limitspage in the docs.
一般来说,没有。Firebase 本质上是一个“实时数据库”,随着数据的变化不断向您流式传输更新,因此进行通用查询更加困难。目前,提供了几个(公认有限的)查询原语。请参阅文档中的查询/限制页面。
You can often work around these limitations through a variety of approaches:
您通常可以通过多种方法解决这些限制:
- Use location names and priorities intelligently.If you structure your data as /users/[userid]/name, you can accomplish your first "query" by just retrieving /users/147/name. If you know you'll want to query by age, you can use age as the priority for user nodes and then do "usersRef.startAt(21).endAt(21).on('child_added', ...)" to get all users age 21. You still have to count them manually.
- Do client-side querying.If the entire data set is smallish, you may be able to retrieve the entire data set and then filter / process it manually on the client.
- Run a separate server. It can connect to Firebase, sync data and then answer "queries" for clients. It can still communicate to clients through Firebase, and Firebase can still be the primary data store, but your separate server can do the work to perform queries quickly.
- 智能地使用位置名称和优先级。如果您将数据结构为 /users/[userid]/name,则只需检索 /users/147/name 即可完成您的第一个“查询”。如果您知道要按年龄查询,则可以使用年龄作为用户节点的优先级,然后执行“usersRef.startAt(21).endAt(21).on('child_ added', ...)”获取所有用户的年龄为 21 岁。您仍然需要手动计算他们。
- 做客户端查询。如果整个数据集很小,您可以检索整个数据集,然后在客户端手动过滤/处理它。
- 运行单独的服务器。它可以连接到 Firebase,同步数据,然后为客户端回答“查询”。它仍然可以通过 Firebase 与客户端通信,并且 Firebase 仍然可以作为主要数据存储,但您的单独服务器可以完成快速执行查询的工作。
We intend to improve on this over time, as we realize it's a weak spot compared to the flexible querying provided by traditional relational database systems.
我们打算随着时间的推移对此进行改进,因为我们意识到与传统关系数据库系统提供的灵活查询相比,这是一个弱点。
回答by Kato
Mr. Lehenbauer is of course the master of all things Firebase, so listen to him. ;) However, this particular topic is one I've been laboring over for a couple of weeks now.
Lehenbauer 先生当然是 Firebase 的大师,所以听他说。;) 然而,这个特定的话题是我已经工作了几个星期了。
Here are a few of my thoughts, to enhance the "Run a separate server" and "Client-side querying" responses:
以下是我的一些想法,以增强“运行单独的服务器”和“客户端查询”响应:
ElasticSearch (a node.js script)
ElasticSearch(一个 node.js 脚本)
With a node.js script on the server, you can have ElasticSearch integrated and providing some solid content searches in under an hour. Here's a blog post and a lib that makes it even easier: https://www.firebase.com/blog/2014-01-02-queries-part-two.html
使用服务器上的 node.js 脚本,您可以集成 ElasticSearch 并在一小时内提供一些可靠的内容搜索。这是一篇博客文章和一个让事情变得更容易的库:https: //www.firebase.com/blog/2014-01-02-queries-part-two.html
cacheable/common queries
可缓存/常见查询
These can be handled by a server/cron process which reads the table and duplicates the data. For instance, assume I want to show "unavailable/available" for a user's login name during registration, but store the user records by a different unique ID for some complex reason.
这些可以由读取表并复制数据的服务器/cron 进程处理。例如,假设我想在注册期间为用户的登录名显示“不可用/可用”,但由于某些复杂的原因,用不同的唯一 ID 存储用户记录。
My cron/server could read all the records from the users table, then insert them into another table that is stored by email address, with a value of the user's record ID (or any other data I might want to know).
我的 cron/server 可以从 users 表中读取所有记录,然后将它们插入到另一个按电子邮件地址存储的表中,其中包含用户记录 ID(或我可能想知道的任何其他数据)的值。
This duplicated data approach is sort a manual caching technique and is a common practice in No-SQL environs; we're trading storage space (which is presumed to be cheap and available) for speed and simplified processes.
这种重复数据方法是一种手动缓存技术,是 No-SQL 环境中的常见做法;我们正在用存储空间(被认为便宜且可用)来换取速度和简化流程。
customized queries (using a queue)
自定义查询(使用队列)
Custom queries could be sent via XHR (ajax) directly to a server, which could do the hard labor and return better results. Alternately, you could utilize Firebase to connect with a server back-end by utilizing a queue.
自定义查询可以通过 XHR (ajax) 直接发送到服务器,服务器可以完成繁重的工作并返回更好的结果。或者,您可以利用 Firebase 通过队列连接到服务器后端。
The client places the query request as a JSON into a special Firebase table called queue
and awaits a response.
客户端将查询请求作为 JSON 放入名为的特殊 Firebase 表中queue
并等待响应。
The server listens for queue.on('child_added', ...)
and serves the data back using `queue_record.child('response', ...data here...)
服务器queue.on('child_added', ...)
使用 `queue_record.child('response', ...data here...)
This has some nice advantages. For one, any number of servers could listen and serve responses, making load balancing a breeze. The code for this is very simplistic to set up and covered in another threadhere in SO.
这有一些不错的优点。一方面,任意数量的服务器都可以监听并提供响应,使负载平衡变得轻而易举。此代码非常简单,可以在 SO中的另一个线程中进行设置和覆盖。
Hope this is helpful!
希望这是有帮助的!
回答by Jakob Hartman
I created my own CMS for firebase so when creating a table of the firebase data i filtered it with this
我为 firebase 创建了自己的 CMS,所以在创建 firebase 数据表时,我用这个过滤了它
var child = ref.child();
var compare;
switch(filter){
case "First_Name":
compare = child.First_Name;
break;
case "Last_Name":
compare = child.Last_Name;
break;
case "Phone_Number":
compare = child.Phone_Number;
break;
case "Department_Number":
compare = child.Department_Number;
break;
case "Position":
compare = child.Position;
break;
case "Status":
compare = child.Status;
break;
case "Tier":
compare = child.Tier;
break;
}
if(compare.match("^" + string)){
//display items