What's the updated and effient way to query sql like in firebase? I've search in forums and they say I should query all the documents then just do a javascript match function
Neither database provided by Firebase (Realtime Database and Firestore) have support for LIKE queries. This is not going to change any time soon, as these types of queries do not scale with the sort of indexes provided by these database.
You can do string prefix queries, which is similar to "WHERE field LIKE foo%", but that's all you get.
For Realtime Database, see:
Firebase matching substring
How to perform sql "LIKE" operation on firebase?
Firebase query - Find item with child that contains string
For Firestore, see:
Google Firestore: Query on substring of a property value (text search)
Firestore Comparison Operators - contains, does not contain, starts with
Is there a way to search sub string at Firestore?
Related
I have a project where I use Firebase's real time database. The project has a lot of records so I have been using orderByChild on my queries, so I only get the records I'm interested in and not all records in the node, like so:
return this.angularFireDataBase.database.ref().child('users/').orderByChild('is_supervisor').equalTo('si');
But now I need to get records whose is_supervisor property is null or doesn't even exist. Is this possible? And how?
If I use offset and limit to paginate query, do I need to specify an order?
In other words, a query with no order specified, uses some implicit order, like key order?
In a SQL database, if I don't specify an order, SQL engine will return the results in the order he pleases. So the second time the query is run, the results may be staked in a different order, so offset and limit would not cut the result as wanted.
Making the assumption you want to order your documents by creation date, in Firestore this would need an extra field, as explained in the Firestore documentation (link):
Unlike "push IDs" in the Firebase Realtime Database, Cloud Firestore
auto-generated IDs do not provide any automatic ordering. If you want
to be able to order your documents by creation date, you should store
a timestamp as a field in the documents.
I want to update all records matching a query in Fire/DataStore, how do I do it?
The SQL equivalent will look like
UPDATE transactions SET category = X WHERE category = Y
Seems like to do this I will have to query all records matching category = Y then for each do a set()?
Firestore (like most NoSQL databases) does not support sending update queries directly to the database.
To update documents matching a query, you will indeed first need to execute that query and then update each document.
Does Firestore support something like whereNotEqual?
For example, I need to get exact documents where key "xyz" is missing.
In Firebase realtime db, we could get it by calling *.equalTo(null).
Thanks.
Firestore does not support a direct equivalent of !=. The supported query operators are <, <=, ==, >, or >= so there's no "whereNotEqual".
You can test if a field exists at all, because all filters and order bys implicitly create a filter on whether or not a field exists. For example, in the Android SDK:
collection.orderBy("name")
would return only those rows that contain a "name" field.
As with explicit comparison there's no way to invert this query to return those rows where a value does not exist.
There are a few work-arounds. The most direct replacement is to explicitly store null then query collection.whereEqualTo("name", null). This is somewhat annoying though because if you don't populate this from the outset you have to backfill existing data once you want to do this. If you can't upgrade all your clients you'll need to deploy a function to keep this field populated.
Another possibility is to observe that usually missing fields indicate that a document is only partially assembled perhaps because it goes through some state machine or is a sort of union of two non-overlapping types. If you explicitly record the state or type as a discriminant you can query on that rather than field non-presence. This works really well when there are only two states/types but gets messy if there are many states.
Cloud Firestore now supports whereNotEqualTo in database queries.
Keep in mind if you have more than one field in your query you may have to create a composite index in Cloud Firestore.
I have the following structure in my DB:
MessagesInvolvingUserID:
- [UserID01]:
- [MessageID01]: [TimeStamp01]
- [MessageID02]: [TimeStamp02]
...
- [UserID02]:
- [MessageID03]: [TimeStamp03]
- [MessageID04]: [TimeStamp04]
...
I'm wondering how to efficiently construct a Dictionary representing the latest messageID (based on timestamp value) for each UserID ?
I think a "brute force" approach would work:
observe MessagesInvolvingUserID for value
loop over every snapshot the filter the latest message ID
construct the Dictionary
But that seems awfully inefficient since that involves downloading and doing the work client side. Any suggestion for a more elegant approach ?
Why don’t you make a Timestamp key under each message with timestamp value and then query messages sorting them by their timestamps? What language are you using to query items from the database? Have you tried something like:
ref.child(“MessagesInvolvingUserID”).child(userID).child("MessageID01").queryOrderedByChild("timestamp").observeEventType(.ChildAdded, withBlock: { snapshot in ...
If you want to have a list that shows the latest timestamp for each user, you should store a list that shows the latest timestamp for each user in your database.
LatestTimstampForUserID:
- [UserID01]: [TimeStamp02]
- [UserID02]: [TimeStamp04]
...
Now you can very efficiently read this data from the database and show the list.
The cost is that you'll need to update multiple locations in the database when a new message is posted for a user. This is very common when using NoSQL databases, such as the Firebase Realtime Database.