Firestore: how to perform a query with inequality

2019-01-01 16:01发布

问题:

I want select from Firestore collection just articles written NOT by me.
Is it really so hard?

Every article has field \"owner_uid\".

Thats it:
I JUST want to write equivalent to \"select * from articles where uid<>request.auth.uid\"

回答1:

Firestore doesn\'t provide inequality checks. According to the documentation:

The where() method takes three parameters: a field to filter on, a comparison operation, and a value. The comparison can be <, <=, ==, >, or >=.

Inequality operations don\'t scale like other operations that use an index. Firestore indexes are good for range queries. With this type of index, for an inequality query, the backend would still have to scan every document in the collection in order to come up with results, and that\'s extremely bad for performance when the number of documents grows large.

If you need to filter your results to remove particular items, you can still do that locally.

You also have the option of using multiple queries to exclude a distinct value. Something like this, if you want everything except 12. Query for value < 12, then query for value > 12, then merge the results in the client.



回答2:

I think it\'s a bit unfair to criticize Firestore in this case. Firestore\'s value proposition is performance and it is purposefully designed for read performance. If your primary requisite is query versatility, for example, Firestore may not be your number one; versatility and performance in this case are inversely correlated (to what degree, I have no idea--would be interesting to see a line graph). Remember, we\'re always striving for an MVP. And when we\'re working with performance-based databases, like Firestore, we should strive for MVQ--minimally-viable query.

In OP\'s case, just how important is this inequality query to you? If it doesn\'t fit your MVQ, get rid of it. If it\'s that important, are there a number of particular strings that need to be queried against? Does the user ever need to query against the word \"and\", for example? Probably not. Consider using a cloud function that listens for these substrings and when they appear or disappear, the function toggles a boolean in the parent document that lets you know which documents have or don\'t have these words. You can now perform a string inequality query without having to iterate through the entire collection (because the boolean is indexed), without performing two queries, without using range operators, and without parsing results locally.



回答3:

From the firebase documentation

Queries with a != clause. In this case, you should split the query into a greater-than query and a less-than query. For example, although the query clause where(\"age\", \"!=\", \"30\") is not supported, you can get the same result set by combining two queries, one with the clause where(\"age\", \"<\", \"30\") and one with the clause where(\"age\", \">\", 30).