How to perform complex logical OR queries in Cloud Firestore?

From documents :

You can also link several where () methods to create more specific queries (logical AND).

How to execute an OR request? Example:

  • Give me all the docs where the status field is open OR upcoming
  • Give me all the documents where the status == open field OR createdAt <= <somedatetime>
+23
source share
6 answers

OR not supported, as it is difficult for the server to scale it (you need to save state for deduplication). The work around is to issue 2 requests, one for each condition and deduction on the client.

+15
source

you can link two Observables using the rxjs merge operator. Here you have an example.

 import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/merge'; ... getCombinatedStatus(): Observable<any> { return Observable.merge(this.db.collection('foo', ref => ref.where('status','==','open')).valueChanges(), this.db.collection('foo', ref => ref.where('status','==','upcoming')).valueChanges()); } 

You can then subscribe to new Observable updates using the method described above:

 getCombinatedStatus.subscribe(results => console.log(results); 

Hope this helps you, hello from Chile!

+2
source

I would not have a "status" field, but there would be fields related to the status, updating them to true or false depending on the request, for example

 { name: "a", status_open: true, status_upcoming: false, status_closed: false} 

However, check out Firebase Cloud Functions. You could have a function to listen for state changes by updating state-related properties, such as

 { name: "a", status: "open", status_open: true, status_upcoming: false, status_closed: false} 

one or the other, your request may just be

 ...where('status_open','==',true)... 

Hope this helps.

+2
source

I also propose giving value to the status.
the ex.

 { name: "a", statusValue = 10, status = 'open' } { name: "b", statusValue = 20, status = 'upcoming'} { name: "c", statusValue = 30, status = 'close'} 

you can request ref.where('statusValue', '<=', 20) , then both 'a' and 'b' will be found.

It can save your cost and performance.

btw, it does not record all cases.

+1
source

We have the same problem now, fortunately, the only possible values โ€‹โ€‹for us are A, B, C, D (4), so we need to request things like A || B, A || C, A || B || C, D, etc.


Like a few months ago, Firebase supports a new array-contains request, so we make an array and pre-process the OR values โ€‹โ€‹in the array

 if (a) { array addObject:@"a" } if (b) { array addObject:@"b" } if (a||b) { array addObject:@"a||b" } etc 

And we do it for all 4! values 4! or any number of combinations.

THEN we can just check the query [document arrayContains:@"a||c"] or any other type of condition that we need.

Therefore, if something qualifies only for conditional A from our 4 conditional expressions (A, B, C, D), then its array will contain the following string literals: @["A", "A||B", "A||C", "A||D", "A||B||C", "A||B||D", "A||C||D", "A||B||C||D"]

Then for any of these OR combinations, we can simply search for array-contains on what we might want (for example, "A || C")


Note. This is a smart approach if you have several possible values โ€‹โ€‹to compare OR.

More information about Array - contains here , as he is new to Firebase docs

+1
source

OR not supported

But if you need it, you can do it in your code

Example: if I want to request products where ( size is Xl or XXL: and gender is male)

 productsCollectionRef //1* first get query where can firestore handle it .whereEqualTo("gender", "Male") .addSnapshotListener((queryDocumentSnapshots, e) -> { if (queryDocumentSnapshots == null) return; List<Product> productList = new ArrayList<>(); for (DocumentSnapshot snapshot : queryDocumentSnapshots.getDocuments()) { Product product = snapshot.toObject(Product.class); //2* then check your query OR Condition because firestore just support AND Condition if (product.getSize().equals("XL") || product.getSize().equals("XXL")) productList.add(product); } liveData.setValue(productList); }); 
0
source

Source: https://habr.com/ru/post/1274675/


All Articles