Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore database query, ignore case (case insenstive) and like clause. [duplicate]

Basically I am writing a search function on a Firestore document field. I want to write equivalent of below SQL. I am not finding solution to proceed.

SELECT * FROM employee WHERE lower(employee_name) LIKE '%johny%';

like image 578
Vijay Keshri Avatar asked Apr 24 '18 15:04

Vijay Keshri


People also ask

Are firestore queries case sensitive?

Save this answer. Show activity on this post. Yes, queries are still case sensitive.

How do I stop duplicate files in firestore?

The best way to prevent duplicate nodes in firebase realtime database or duplicate documents in firebase firestore database is to keep a check in the app itself to verify that the record to be inserted doesn't already exist in the database by querying for data using key field in where clause.

How do I get distinct values on firestore?

There is no specific API to retrieve unique values from Cloud Firestore. You will have to retrieve all relevant documents and determine the unique names in your own code. Alternatively, consider adding a document with unique names and update that with every write.

How do I iterate through firestore collection?

Yes, you can simply query the collection for all its documents using the get() method on the collection reference. A CollectionReference object subclasses Query, so you can call Query methods on it. By itself, a collection reference is essentially an unfiltered query for all of its documents.


3 Answers

There is no like operator. See all available operators at: https://firebase.google.com/docs/firestore/query-data/queries The page also contains different ways on querying the database.

For case insensitive sorting / querying please see the answer at Cloud Firestore Case Insensitive Sorting Using Query

It basically advises to store your lowercase data in an additional field.

like image 106
Norman Avatar answered Nov 05 '22 21:11

Norman


Probably answered this under the wrong topic on the other post, but check out my answer here

The solution works for me so far, but I split the name into first and last name. Then "starts with" (LIKE search%) logic should suffice since IMO people normally start typing the beginning of the names rather than something that would require a "contains" match (LIKE %search%).

Just in case the other post gets deleted due to wrong section (if that's possible) here's the snippet from firestore client perspective:

from firebase_admin import firestore 
users = db.collection("users")\
        .order_by("last_name")\
        .where("last_name", ">=", last_name.upper())\
        .where("last_name", "<=", last_name.lower() + "\uf8ff")\
        .stream()

Edit 09-03-2020 This works a portion of the time it seems. Most of the time I didn't seem to have an issue, but when I applied it to another project I was getting unexpected results. Long story short you may need to replicate how you save the data you're comparing against. For example, you may need to have a field to save the last_name in all caps and another field to save it in all lowercase, then you change the first where clause to compare last_name_upper and the second to compare last_name_lowercase. In my second project so far this seems to yield more accurate results so you may want to give that a try if the previous answer doesn't work well

EDIT 09-07-2020 Previous edit from 09-03-2020 is partially accurate. During my haste of thinking I had it fully resolved I completely forgot firebase doesn't let you use <, >, <=, >= across different fields. You may need to do two queries and merge them, but you'd probably still be reading more docs than you really intend. Doing the comparison against either the upper or lower version with the appropriate search term seems to give the original results expected from the original answer. For example:

.orderBy("last_name_upper")
    .where("last_name_upper", ">=", this.searchForm.text.toUpperCase())
    .where("last_name_upper", "<=", this.searchForm.text.toUpperCase() + "\uf8ff")
like image 23
MattT Avatar answered Nov 05 '22 21:11

MattT


As Norman already wrote, there is no LIKE operator in Firebase.

I wrote an answer in SO that explains how to achieve a similar query (even if it is a StartWith search, rather than a full text search):

databaseReference.orderByChild('_searchLastName')
             .startAt(queryText)
             .endAt(queryText+"\uf8ff")
             .once("value")

If you need more advanced ways of searching, then the advice is to use ElasticSearch, as a possible solution.

like image 2
Francesco Avatar answered Nov 05 '22 21:11

Francesco