How to perform compound queries with logical OR in Cloud Firestore?

后端 未结 9 1600
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 02:07

From the docs:

You can also chain multiple where() methods to create more specific queries (logical AND).

How can I perform an <

相关标签:
9条回答
  • 2020-11-22 02:26

    This doesn't solve all cases, but for "enum" fields, you can emulate an "OR" query by making a separate boolean field for each enum-value, then adding a where("enum_<value>", "==", false) for every value that isn't part of the "OR" clause you want.

    For example, consider your first desired query:

    1. Give me all documents where the field status is open OR upcoming

    You can accomplish this by splitting the status: string field into multiple boolean fields, one for each enum-value:

    status_open: bool
    status_upcoming: bool
    status_suspended: bool
    status_closed: bool
    

    To perform your "where status is open or upcoming" query, you then do this:

    where("status_suspended", "==", false).where("status_closed", "==", false)
    

    How does this work? Well, because it's an enum, you know one of the values must have true assigned. So if you can determine that all of the other values don't match for a given entry, then by deduction it must match one of the values you originally were looking for.

    0 讨论(0)
  • 2020-11-22 02:27

    OR isn't supported

    But if you need that you can do It in your code

    Ex : if i want query products where (Size Equal 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 讨论(0)
  • 2020-11-22 02:31

    We have the same problem just now, luckily the only possible values for ours are A,B,C,D (4) so we have to query for things like A||B, A||C, A||B||C, D, etc


    As of like a few months ago firebase supports a new query array-contains so what we do is make an array and we pre-process the OR values to the array

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

    And we do this for all 4! values or however many combos there are.

    THEN we can simply check the query [document arrayContains:@"a||c"] or whatever type of condition we need.

    So if something only qualified for conditional A of our 4 conditionals (A,B,C,D) then its array would contain the following literal strings: @["A", "A||B", "A||C", "A||D", "A||B||C", "A||B||D", "A||C||D", "A||B||C||D"]

    Then for any of those OR combinations we can just search array-contains on whatever we may want (e.g. "A||C")


    Note: This is only a reasonable approach if you have a few number of possible values to compare OR with.

    More info on Array-contains here, since it's newish to firebase docs

    0 讨论(0)
  • 2020-11-22 02:31

    For Flutter dart language use this:

    db.collection("projects").where("status", whereIn: ["public", "unlisted", "secret"]);
    
    0 讨论(0)
  • 2020-11-22 02:34

    With the recent addition of IN queries, Firestore supports "up to 10 equality clauses on the same field with a logical OR"

    A possible solution to (1) would be:

    documents.where('status', 'in', ['open', 'upcoming']);
    
    

    See Firebase Guides: Query Operators | in and array-contains-any

    0 讨论(0)
  • 2020-11-22 02:34

    suggest to give value for status as well.
    ex.

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

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

    this can save your query cost and performance.

    btw, it is not fix all case.

    0 讨论(0)
提交回复
热议问题