@@ -368,12 +368,13 @@ public void testDeeplyNestedServerTimestamps() {
368
368
}
369
369
370
370
@ Test
371
- public void testIndexAutoCreationWorks () {
371
+ public void testCanAutoCreateIndexes () {
372
372
Query query = query ("coll" ).filter (filter ("matches" , "==" , true ));
373
373
int targetId = allocateQuery (query );
374
374
375
375
enableIndexAutoCreation ();
376
376
setMinCollectionSizeToAutoCreateIndex (0 );
377
+ setRelativeIndexReadCost (2 );
377
378
378
379
applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("matches" , true )), targetId ));
379
380
applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("matches" , false )), targetId ));
@@ -398,17 +399,18 @@ public void testIndexAutoCreationWorks() {
398
399
}
399
400
400
401
@ Test
401
- public void testIndexAutoCreationDoesNotWorkWhenCollectionSizeIsTooSmall () {
402
- Query query = query ("coll" ).filter (filter ("matches " , "== " , true ));
402
+ public void testDoesNotAutoCreateIndexesForSmallCollections () {
403
+ Query query = query ("coll" ).filter (filter ("count " , ">= " , 3 ));
403
404
int targetId = allocateQuery (query );
404
405
405
406
enableIndexAutoCreation ();
407
+ setRelativeIndexReadCost (2 );
406
408
407
- applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("matches " , true )), targetId ));
408
- applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("matches " , false )), targetId ));
409
- applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("matches " , false )), targetId ));
410
- applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("matches " , false )), targetId ));
411
- applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("matches " , true )), targetId ));
409
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("count " , 5 )), targetId ));
410
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("count " , 1 )), targetId ));
411
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("count " , 0 )), targetId ));
412
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("count " , 1 )), targetId ));
413
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("count " , 3 )), targetId ));
412
414
413
415
// SDK will not create indexes since collection size is too small.
414
416
executeQuery (query );
@@ -417,7 +419,41 @@ public void testIndexAutoCreationDoesNotWorkWhenCollectionSizeIsTooSmall() {
417
419
418
420
backfillIndexes ();
419
421
420
- applyRemoteEvent (addedRemoteEvent (doc ("coll/f" , 20 , map ("matches" , true )), targetId ));
422
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/f" , 20 , map ("count" , 4 )), targetId ));
423
+
424
+ executeQuery (query );
425
+ assertRemoteDocumentsRead (/* byKey= */ 0 , /* byCollection= */ 3 );
426
+ assertQueryReturned ("coll/a" , "coll/e" , "coll/f" );
427
+ }
428
+
429
+ @ Test
430
+ public void testDoesNotAutoCreateIndexesWhenIndexLookUpIsExpensive () {
431
+ Query query = query ("coll" ).filter (filter ("array" , "array-contains-any" , Arrays .asList (0 , 7 )));
432
+ int targetId = allocateQuery (query );
433
+
434
+ enableIndexAutoCreation ();
435
+ setMinCollectionSizeToAutoCreateIndex (0 );
436
+ setRelativeIndexReadCost (5 );
437
+
438
+ applyRemoteEvent (
439
+ addedRemoteEvent (doc ("coll/a" , 10 , map ("array" , Arrays .asList (2 , 7 ))), targetId ));
440
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("array" , emptyList ())), targetId ));
441
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("array" , singletonList (3 ))), targetId ));
442
+ applyRemoteEvent (
443
+ addedRemoteEvent (doc ("coll/d" , 10 , map ("array" , Arrays .asList (2 , 10 , 20 ))), targetId ));
444
+ applyRemoteEvent (
445
+ addedRemoteEvent (doc ("coll/e" , 10 , map ("array" , Arrays .asList (2 , 0 , 8 ))), targetId ));
446
+
447
+ // First time query runs without indexes.
448
+ // Based on current heuristic, collection document counts (5) > 2 * resultSize (2).
449
+ // Full matched index should be created.
450
+ executeQuery (query );
451
+ assertRemoteDocumentsRead (/* byKey= */ 0 , /* byCollection= */ 2 );
452
+ assertQueryReturned ("coll/a" , "coll/e" );
453
+
454
+ backfillIndexes ();
455
+
456
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/f" , 20 , map ("array" , singletonList (0 ))), targetId ));
421
457
422
458
executeQuery (query );
423
459
assertRemoteDocumentsRead (/* byKey= */ 0 , /* byCollection= */ 3 );
@@ -426,17 +462,18 @@ public void testIndexAutoCreationDoesNotWorkWhenCollectionSizeIsTooSmall() {
426
462
427
463
@ Test
428
464
public void testIndexAutoCreationWorksWhenBackfillerRunsHalfway () {
429
- Query query = query ("coll" ).filter (filter ("matches" , "==" , true ));
465
+ Query query = query ("coll" ).filter (filter ("matches" , "==" , "foo" ));
430
466
int targetId = allocateQuery (query );
431
467
432
468
enableIndexAutoCreation ();
433
469
setMinCollectionSizeToAutoCreateIndex (0 );
470
+ setRelativeIndexReadCost (2 );
434
471
435
- applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("matches" , true )), targetId ));
436
- applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("matches" , false )), targetId ));
437
- applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("matches" , false )), targetId ));
438
- applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("matches" , false )), targetId ));
439
- applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("matches" , true )), targetId ));
472
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("matches" , "foo" )), targetId ));
473
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("matches" , "" )), targetId ));
474
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("matches" , "bar" )), targetId ));
475
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("matches" , 7 )), targetId ));
476
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("matches" , "foo" )), targetId ));
440
477
441
478
// First time query is running without indexes.
442
479
// Based on current heuristic, collection document counts (5) > 2 * resultSize (2).
@@ -449,7 +486,7 @@ public void testIndexAutoCreationWorksWhenBackfillerRunsHalfway() {
449
486
setBackfillerMaxDocumentsToProcess (2 );
450
487
backfillIndexes ();
451
488
452
- applyRemoteEvent (addedRemoteEvent (doc ("coll/f" , 20 , map ("matches" , true )), targetId ));
489
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/f" , 20 , map ("matches" , "foo" )), targetId ));
453
490
454
491
executeQuery (query );
455
492
assertRemoteDocumentsRead (/* byKey= */ 1 , /* byCollection= */ 2 );
@@ -458,17 +495,18 @@ public void testIndexAutoCreationWorksWhenBackfillerRunsHalfway() {
458
495
459
496
@ Test
460
497
public void testIndexCreatedByIndexAutoCreationExistsAfterTurnOffAutoCreation () {
461
- Query query = query ("coll" ).filter (filter ("matches " , "== " , true ));
498
+ Query query = query ("coll" ).filter (filter ("value " , "not-in " , Collections . singletonList ( 3 ) ));
462
499
int targetId = allocateQuery (query );
463
500
464
501
enableIndexAutoCreation ();
465
502
setMinCollectionSizeToAutoCreateIndex (0 );
503
+ setRelativeIndexReadCost (2 );
466
504
467
- applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("matches " , true )), targetId ));
468
- applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("matches " , false )), targetId ));
469
- applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("matches " , false )), targetId ));
470
- applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("matches " , false )), targetId ));
471
- applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("matches " , true )), targetId ));
505
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("value " , 5 )), targetId ));
506
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("value " , 3 )), targetId ));
507
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("value " , 3 )), targetId ));
508
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("value " , 3 )), targetId ));
509
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("value " , 2 )), targetId ));
472
510
473
511
// First time query runs without indexes.
474
512
// Based on current heuristic, collection document counts (5) > 2 * resultSize (2).
@@ -481,7 +519,7 @@ public void testIndexCreatedByIndexAutoCreationExistsAfterTurnOffAutoCreation()
481
519
482
520
backfillIndexes ();
483
521
484
- applyRemoteEvent (addedRemoteEvent (doc ("coll/f" , 20 , map ("matches " , true )), targetId ));
522
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/f" , 20 , map ("value " , 7 )), targetId ));
485
523
486
524
executeQuery (query );
487
525
assertRemoteDocumentsRead (/* byKey= */ 2 , /* byCollection= */ 1 );
@@ -490,17 +528,18 @@ public void testIndexCreatedByIndexAutoCreationExistsAfterTurnOffAutoCreation()
490
528
491
529
@ Test
492
530
public void testDisableIndexAutoCreationWorks () {
493
- Query query1 = query ("coll" ).filter (filter ("matches " , "== " , true ));
531
+ Query query1 = query ("coll" ).filter (filter ("value " , "in " , Arrays . asList ( 0 , 1 ) ));
494
532
int targetId1 = allocateQuery (query1 );
495
533
496
534
enableIndexAutoCreation ();
497
535
setMinCollectionSizeToAutoCreateIndex (0 );
536
+ setRelativeIndexReadCost (2 );
498
537
499
- applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("matches " , true )), targetId1 ));
500
- applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("matches " , false )), targetId1 ));
501
- applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("matches " , false )), targetId1 ));
502
- applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("matches " , false )), targetId1 ));
503
- applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("matches " , true )), targetId1 ));
538
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("value " , 1 )), targetId1 ));
539
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("value " , 8 )), targetId1 ));
540
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("value " , "string" )), targetId1 ));
541
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("value " , false )), targetId1 ));
542
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("value " , 0 )), targetId1 ));
504
543
505
544
// First time query is running without indexes.
506
545
// Based on current heuristic, collection document counts (5) > 2 * resultSize (2).
@@ -517,36 +556,43 @@ public void testDisableIndexAutoCreationWorks() {
517
556
assertRemoteDocumentsRead (/* byKey= */ 2 , /* byCollection= */ 0 );
518
557
assertQueryReturned ("coll/a" , "coll/e" );
519
558
520
- Query query2 = query ("foo" ).filter (filter ("matches " , "== " , true ));
559
+ Query query2 = query ("foo" ).filter (filter ("value " , "!= " , Double . NaN ));
521
560
int targetId2 = allocateQuery (query2 );
522
561
523
- applyRemoteEvent (addedRemoteEvent (doc ("foo/a" , 10 , map ("matches " , true )), targetId2 ));
524
- applyRemoteEvent (addedRemoteEvent (doc ("foo/b" , 10 , map ("matches " , false )), targetId2 ));
525
- applyRemoteEvent (addedRemoteEvent (doc ("foo/c" , 10 , map ("matches " , false )), targetId2 ));
526
- applyRemoteEvent (addedRemoteEvent (doc ("foo/d" , 10 , map ("matches " , false )), targetId2 ));
527
- applyRemoteEvent (addedRemoteEvent (doc ("foo/e" , 10 , map ("matches " , true )), targetId2 ));
562
+ applyRemoteEvent (addedRemoteEvent (doc ("foo/a" , 10 , map ("value " , 5 )), targetId2 ));
563
+ applyRemoteEvent (addedRemoteEvent (doc ("foo/b" , 10 , map ("value " , Double . NaN )), targetId2 ));
564
+ applyRemoteEvent (addedRemoteEvent (doc ("foo/c" , 10 , map ("value " , Double . NaN )), targetId2 ));
565
+ applyRemoteEvent (addedRemoteEvent (doc ("foo/d" , 10 , map ("value " , Double . NaN )), targetId2 ));
566
+ applyRemoteEvent (addedRemoteEvent (doc ("foo/e" , 10 , map ("value " , "string" )), targetId2 ));
528
567
529
568
executeQuery (query2 );
530
569
assertRemoteDocumentsRead (/* byKey= */ 0 , /* byCollection= */ 2 );
531
570
571
+ backfillIndexes ();
572
+
532
573
// Run the query in second time, test index won't be created
533
574
executeQuery (query2 );
534
575
assertRemoteDocumentsRead (/* byKey= */ 0 , /* byCollection= */ 2 );
535
576
}
536
577
537
578
@ Test
538
579
public void testIndexAutoCreationWorksWithMutation () {
539
- Query query = query ("coll" ).filter (filter ("matches" , "==" , true ));
580
+ Query query =
581
+ query ("coll" ).filter (filter ("value" , "array-contains-any" , Arrays .asList (8 , 1 , "string" )));
540
582
int targetId = allocateQuery (query );
541
583
542
584
enableIndexAutoCreation ();
543
585
setMinCollectionSizeToAutoCreateIndex (0 );
586
+ setRelativeIndexReadCost (2 );
544
587
545
- applyRemoteEvent (addedRemoteEvent (doc ("coll/a" , 10 , map ("matches" , true )), targetId ));
546
- applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("matches" , false )), targetId ));
547
- applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("matches" , false )), targetId ));
548
- applyRemoteEvent (addedRemoteEvent (doc ("coll/d" , 10 , map ("matches" , false )), targetId ));
549
- applyRemoteEvent (addedRemoteEvent (doc ("coll/e" , 10 , map ("matches" , true )), targetId ));
588
+ applyRemoteEvent (
589
+ addedRemoteEvent (doc ("coll/a" , 10 , map ("value" , Arrays .asList (8 , 1 , "string" ))), targetId ));
590
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/b" , 10 , map ("value" , emptyList ())), targetId ));
591
+ applyRemoteEvent (addedRemoteEvent (doc ("coll/c" , 10 , map ("value" , singletonList (3 ))), targetId ));
592
+ applyRemoteEvent (
593
+ addedRemoteEvent (doc ("coll/d" , 10 , map ("value" , Arrays .asList (0 , 5 ))), targetId ));
594
+ applyRemoteEvent (
595
+ addedRemoteEvent (doc ("coll/e" , 10 , map ("value" , singletonList ("string" ))), targetId ));
550
596
551
597
executeQuery (query );
552
598
assertRemoteDocumentsRead (/* byKey= */ 0 , /* byCollection= */ 2 );
@@ -556,7 +602,7 @@ public void testIndexAutoCreationWorksWithMutation() {
556
602
557
603
backfillIndexes ();
558
604
559
- writeMutation (setMutation ("coll/f" , map ("matches " , true )));
605
+ writeMutation (setMutation ("coll/f" , map ("value " , singletonList ( 1 ) )));
560
606
561
607
executeQuery (query );
562
608
assertRemoteDocumentsRead (/* byKey= */ 1 , /* byCollection= */ 0 );
0 commit comments