GeoFlutterFire icon indicating copy to clipboard operation
GeoFlutterFire copied to clipboard

Issue when using where() to filter causing extra reads

Open momoDragon opened this issue 5 years ago • 19 comments

Code collectionRef: Firestore.instance .collection('vendors') .where('storeType', isEqualTo: 'Cafe') .where('vendorType', isEqualTo: 2).where('block', isEqualTo: false) .where('applicationStatus', isEqualTo: 3).where('isVisible', isEqualTo: true)

Scenario As u can see i am using where(). However its causing me extra reads. I have 100 items in 10km radius, but only one of them meets the criteria .where('storeType', isEqualTo: 'Cafe) But this caused me 100 reads.

momoDragon avatar Apr 20 '19 10:04 momoDragon

I believe each .where() is basically an OR statement that is being merged when they arrive, so it kinda makes sense that it results in multiple reads.

japborst avatar Apr 24 '19 19:04 japborst

Not possible to incorporate .where() when doing the geoquery rather than do it after the query? Because without its, its not very flexible for doing querys hence causing extra unnecessary doc reads

momoDragon avatar Apr 25 '19 03:04 momoDragon

@momoDragon .where() is supposed to just give you 1 read, I'm sure this has been the case from the first version when used with isEqualTo, it uses the same query as cloud_firestore. Could you verify again?

DarshanGowda0 avatar Apr 25 '19 13:04 DarshanGowda0

I'm surprised you got a read at all. I tried filtering my collection with a where clause and it seemed to have not work. I checked multiple times to see if it is right collection, field, and value and they were all correct, but still no read. When I would take the where clause out, all the records come through.

mike-gallego avatar May 01 '19 19:05 mike-gallego

@mikeyyg96 .where() works only with isEqualTo at the moment. And also are you creating index the first time?

DarshanGowda0 avatar May 01 '19 19:05 DarshanGowda0

@DarshanGowda0 Yeah I used the exact format in the documentation: var queryRef = _firestore.collection('locations').where('city', isEqualTo: 'bangalore'); but with my values: var queryRef = _firestore.collection('events').where('category', isEqualTo: 'activities'); I have this field in my collection and that value as well but nothing returns. When I take out the where clause, the record pops up. It is only 1 record in my collection. Screenshot_20190501-153146__01

mike-gallego avatar May 01 '19 19:05 mike-gallego

Yes i have tested. and ya. its quite bad. its causing me hell alot of reads man. @DarshanGowda0 u need to try it again man. Open a new project and use app engine to track the usage.

momoDragon avatar May 02 '19 08:05 momoDragon

@DarshanGowda0 Yeah I used the exact format in the documentation: var queryRef = _firestore.collection('locations').where('city', isEqualTo: 'bangalore'); but with my values: var queryRef = _firestore.collection('events').where('category', isEqualTo: 'activities'); I have this field in my collection and that value as well but nothing returns. When I take out the where clause, the record pops up. It is only 1 record in my collection. Screenshot_20190501-153146__01

Check your console. it would prompt u to create index. there will be a link. just click it

momoDragon avatar May 02 '19 08:05 momoDragon

@momoDragon Can you please show me where that link is located or what exactly is it saying? I have a lot of information in my console and it keeps updating and filtering the console with vscode sucks.

Edit: BTW, did you try strictMode: true? Maybe that'll help.

mike-gallego avatar May 02 '19 13:05 mike-gallego

@mikeyyg96 yup. I always use strict mode

momoDragon avatar May 02 '19 17:05 momoDragon

Hey @momoDragon! I verified this again, the number of reads is always 1 if I have just one document that satisfies the where() condition. The firestore query you pass is the first condition that is executed and geofire filtering happens after the where() filter is done (check this).

DarshanGowda0 avatar May 04 '19 13:05 DarshanGowda0

I have sort of a similar issue. When I use a where clause the stream never returns back:

var query = Firestore.instance
        .collection('itineraries')
        .where('status', isEqualTo: status.toString());

    GeoFirePoint center =
        geo.point(latitude: nearby.latitude, longitude: nearby.longitude);

    double radius = 50;
    String field = 'position';

    Stream<List<DocumentSnapshot>> stream = geo
        .collection(collectionRef: query)
        .within(center: center, radius: radius, field: field);

    List<DocumentSnapshot> docs = await stream.first;

if I remove the where it works fine. I have created the composite index in different ways manually as I never get the link to create it image image Am I missing something here?

rmelian avatar Jun 16 '19 03:06 rmelian

Same issue as rmelian's. Like rmelian, I never get the link to create the composite index.

Moellendorff avatar Jun 27 '19 08:06 Moellendorff

@rmelian Solved by manually creating an index that, in your terms, would be: Collection ID: itineraries Field indexed: status Ascending position.geohash Ascending Query scope: Collection

Moellendorff avatar Jun 27 '19 09:06 Moellendorff

i have sort of the same issue: var collectionRef = Firestore.instance.collection('/user_data').where('gender', isEqualTo: 'male');

return geo .collection(collectionRef: collectionRef.reference()) .within(center: center, radius: 1, field: 'location');

it totally ignores the .where, and just outputs all users within the radius.

yevgeniaronov avatar Dec 20 '19 12:12 yevgeniaronov

@rmelian Solved by manually creating an index that, in your terms, would be: Collection ID: itineraries Field indexed: status Ascending position.geohash Ascending Query scope: Collection

is need sequins as where conditions and then position.geohash index look like status_position.geohash

ghost avatar Dec 31 '19 19:12 ghost

@atozbtcom and @Moellendorff are right. I just verified that. @yevgeniaronov u need to manually set indexing in firebase console.

ensure that u sort the where clause field first before the position.geohash Screenshot 2020-01-01 at 11 27 08 AM

momoDragon avatar Jan 01 '20 03:01 momoDragon

@momoDragon So position.geohash must be the last field when setting up the index?

Update - That did not work for me either

atnegrete avatar Feb 15 '20 05:02 atnegrete

query still not working after creating composite index. did anyone find a solution for this? Thank you!

smolugu avatar Sep 16 '20 07:09 smolugu