1919import static com .google .firebase .firestore .pipeline .Function .and ;
2020import static com .google .firebase .firestore .pipeline .Function .arrayContains ;
2121import static com .google .firebase .firestore .pipeline .Function .arrayContainsAny ;
22+ import static com .google .firebase .firestore .pipeline .Function .cosineDistance ;
2223import static com .google .firebase .firestore .pipeline .Function .endsWith ;
2324import static com .google .firebase .firestore .pipeline .Function .eq ;
25+ import static com .google .firebase .firestore .pipeline .Function .euclideanDistance ;
2426import static com .google .firebase .firestore .pipeline .Function .gt ;
27+ import static com .google .firebase .firestore .pipeline .Function .logicalMax ;
28+ import static com .google .firebase .firestore .pipeline .Function .logicalMin ;
2529import static com .google .firebase .firestore .pipeline .Function .lt ;
2630import static com .google .firebase .firestore .pipeline .Function .lte ;
2731import static com .google .firebase .firestore .pipeline .Function .neq ;
4145import com .google .common .truth .Correspondence ;
4246import com .google .firebase .firestore .pipeline .Accumulator ;
4347import com .google .firebase .firestore .pipeline .AggregateStage ;
48+ import com .google .firebase .firestore .pipeline .Constant ;
4449import com .google .firebase .firestore .pipeline .Field ;
4550import com .google .firebase .firestore .pipeline .Function ;
4651import com .google .firebase .firestore .testutil .IntegrationTestUtil ;
52+ import java .util .Collections ;
53+ import java .util .LinkedHashMap ;
4754import java .util .Map ;
4855import java .util .Objects ;
4956import org .junit .After ;
@@ -87,11 +94,11 @@ public void tearDown() {
8794 IntegrationTestUtil .tearDown ();
8895 }
8996
90- private Map <String , Map <String , Object >> bookDocs =
91- ImmutableMap . ofEntries (
97+ private final Map <String , Map <String , Object >> bookDocs =
98+ mapOfEntries (
9299 entry (
93100 "book1" ,
94- ImmutableMap . ofEntries (
101+ mapOfEntries (
95102 entry ("title" , "The Hitchhiker's Guide to the Galaxy" ),
96103 entry ("author" , "Douglas Adams" ),
97104 entry ("genre" , "Science Fiction" ),
@@ -101,7 +108,7 @@ public void tearDown() {
101108 entry ("awards" , ImmutableMap .of ("hugo" , true , "nebula" , false )))),
102109 entry (
103110 "book2" ,
104- ImmutableMap . ofEntries (
111+ mapOfEntries (
105112 entry ("title" , "Pride and Prejudice" ),
106113 entry ("author" , "Jane Austen" ),
107114 entry ("genre" , "Romance" ),
@@ -111,7 +118,7 @@ public void tearDown() {
111118 entry ("awards" , ImmutableMap .of ("none" , true )))),
112119 entry (
113120 "book3" ,
114- ImmutableMap . ofEntries (
121+ mapOfEntries (
115122 entry ("title" , "One Hundred Years of Solitude" ),
116123 entry ("author" , "Gabriel García Márquez" ),
117124 entry ("genre" , "Magical Realism" ),
@@ -121,7 +128,7 @@ public void tearDown() {
121128 entry ("awards" , ImmutableMap .of ("nobel" , true , "nebula" , false )))),
122129 entry (
123130 "book4" ,
124- ImmutableMap . ofEntries (
131+ mapOfEntries (
125132 entry ("title" , "The Lord of the Rings" ),
126133 entry ("author" , "J.R.R. Tolkien" ),
127134 entry ("genre" , "Fantasy" ),
@@ -131,7 +138,7 @@ public void tearDown() {
131138 entry ("awards" , ImmutableMap .of ("hugo" , false , "nebula" , false )))),
132139 entry (
133140 "book5" ,
134- ImmutableMap . ofEntries (
141+ mapOfEntries (
135142 entry ("title" , "The Handmaid's Tale" ),
136143 entry ("author" , "Margaret Atwood" ),
137144 entry ("genre" , "Dystopian" ),
@@ -142,7 +149,7 @@ public void tearDown() {
142149 "awards" , ImmutableMap .of ("arthur c. clarke" , true , "booker prize" , false )))),
143150 entry (
144151 "book6" ,
145- ImmutableMap . ofEntries (
152+ mapOfEntries (
146153 entry ("title" , "Crime and Punishment" ),
147154 entry ("author" , "Fyodor Dostoevsky" ),
148155 entry ("genre" , "Psychological Thriller" ),
@@ -152,7 +159,7 @@ public void tearDown() {
152159 entry ("awards" , ImmutableMap .of ("none" , true )))),
153160 entry (
154161 "book7" ,
155- ImmutableMap . ofEntries (
162+ mapOfEntries (
156163 entry ("title" , "To Kill a Mockingbird" ),
157164 entry ("author" , "Harper Lee" ),
158165 entry ("genre" , "Southern Gothic" ),
@@ -162,7 +169,7 @@ public void tearDown() {
162169 entry ("awards" , ImmutableMap .of ("pulitzer" , true )))),
163170 entry (
164171 "book8" ,
165- ImmutableMap . ofEntries (
172+ mapOfEntries (
166173 entry ("title" , "1984" ),
167174 entry ("author" , "George Orwell" ),
168175 entry ("genre" , "Dystopian" ),
@@ -172,7 +179,7 @@ public void tearDown() {
172179 entry ("awards" , ImmutableMap .of ("prometheus" , true )))),
173180 entry (
174181 "book9" ,
175- ImmutableMap . ofEntries (
182+ mapOfEntries (
176183 entry ("title" , "The Great Gatsby" ),
177184 entry ("author" , "F. Scott Fitzgerald" ),
178185 entry ("genre" , "Modernist" ),
@@ -182,7 +189,7 @@ public void tearDown() {
182189 entry ("awards" , ImmutableMap .of ("none" , true )))),
183190 entry (
184191 "book10" ,
185- ImmutableMap . ofEntries (
192+ mapOfEntries (
186193 entry ("title" , "Dune" ),
187194 entry ("author" , "Frank Herbert" ),
188195 entry ("genre" , "Science Fiction" ),
@@ -239,8 +246,7 @@ public void aggregateResultsMany() {
239246 assertThat (waitFor (execute ).getResults ())
240247 .comparingElementsUsing (DATA_CORRESPONDENCE )
241248 .containsExactly (
242- ImmutableMap .ofEntries (
243- entry ("count" , 10 ), entry ("avgRating" , 4.4 ), entry ("maxRating" , 4.6 )));
249+ mapOfEntries (entry ("count" , 10 ), entry ("avgRating" , 4.4 ), entry ("maxRating" , 4.6 )));
244250 }
245251
246252 @ Test
@@ -259,9 +265,9 @@ public void groupAndAccumulateResults() {
259265 assertThat (waitFor (execute ).getResults ())
260266 .comparingElementsUsing (DATA_CORRESPONDENCE )
261267 .containsExactly (
262- ImmutableMap . ofEntries (entry ("avgRating" , 4.7 ), entry ("genre" , "Fantasy" )),
263- ImmutableMap . ofEntries (entry ("avgRating" , 4.5 ), entry ("genre" , "Romance" )),
264- ImmutableMap . ofEntries (entry ("avgRating" , 4.4 ), entry ("genre" , "Science Fiction" )));
268+ mapOfEntries (entry ("avgRating" , 4.7 ), entry ("genre" , "Fantasy" )),
269+ mapOfEntries (entry ("avgRating" , 4.5 ), entry ("genre" , "Romance" )),
270+ mapOfEntries (entry ("avgRating" , 4.4 ), entry ("genre" , "Science Fiction" )));
265271 }
266272
267273 @ Test
@@ -279,8 +285,7 @@ public void minAndMaxAccumulations() {
279285 assertThat (waitFor (execute ).getResults ())
280286 .comparingElementsUsing (DATA_CORRESPONDENCE )
281287 .containsExactly (
282- ImmutableMap .ofEntries (
283- entry ("count" , 10 ), entry ("maxRating" , 4.7 ), entry ("minPublished" , 1813 )));
288+ mapOfEntries (entry ("count" , 10 ), entry ("maxRating" , 4.7 ), entry ("minPublished" , 1813 )));
284289 }
285290
286291 @ Test
@@ -295,26 +300,23 @@ public void canSelectFields() {
295300 assertThat (waitFor (execute ).getResults ())
296301 .comparingElementsUsing (DATA_CORRESPONDENCE )
297302 .containsExactly (
298- ImmutableMap . ofEntries (
303+ mapOfEntries (
299304 entry ("title" , "The Hitchhiker's Guide to the Galaxy" ),
300305 entry ("author" , "Douglas Adams" )),
301- ImmutableMap . ofEntries (
306+ mapOfEntries (
302307 entry ("title" , "The Great Gatsby" ), entry ("author" , "F. Scott Fitzgerald" )),
303- ImmutableMap . ofEntries (entry ("title" , "Dune" ), entry ("author" , "Frank Herbert" )),
304- ImmutableMap . ofEntries (
308+ mapOfEntries (entry ("title" , "Dune" ), entry ("author" , "Frank Herbert" )),
309+ mapOfEntries (
305310 entry ("title" , "Crime and Punishment" ), entry ("author" , "Fyodor Dostoevsky" )),
306- ImmutableMap . ofEntries (
311+ mapOfEntries (
307312 entry ("title" , "One Hundred Years of Solitude" ),
308313 entry ("author" , "Gabriel García Márquez" )),
309- ImmutableMap .ofEntries (entry ("title" , "1984" ), entry ("author" , "George Orwell" )),
310- ImmutableMap .ofEntries (
311- entry ("title" , "To Kill a Mockingbird" ), entry ("author" , "Harper Lee" )),
312- ImmutableMap .ofEntries (
314+ mapOfEntries (entry ("title" , "1984" ), entry ("author" , "George Orwell" )),
315+ mapOfEntries (entry ("title" , "To Kill a Mockingbird" ), entry ("author" , "Harper Lee" )),
316+ mapOfEntries (
313317 entry ("title" , "The Lord of the Rings" ), entry ("author" , "J.R.R. Tolkien" )),
314- ImmutableMap .ofEntries (
315- entry ("title" , "Pride and Prejudice" ), entry ("author" , "Jane Austen" )),
316- ImmutableMap .ofEntries (
317- entry ("title" , "The Handmaid's Tale" ), entry ("author" , "Margaret Atwood" )))
318+ mapOfEntries (entry ("title" , "Pride and Prejudice" ), entry ("author" , "Jane Austen" )),
319+ mapOfEntries (entry ("title" , "The Handmaid's Tale" ), entry ("author" , "Margaret Atwood" )))
318320 .inOrder ();
319321 }
320322
@@ -362,10 +364,9 @@ public void offsetAndLimits() {
362364 assertThat (waitFor (execute ).getResults ())
363365 .comparingElementsUsing (DATA_CORRESPONDENCE )
364366 .containsExactly (
365- ImmutableMap .ofEntries (entry ("title" , "1984" ), entry ("author" , "George Orwell" )),
366- ImmutableMap .ofEntries (
367- entry ("title" , "To Kill a Mockingbird" ), entry ("author" , "Harper Lee" )),
368- ImmutableMap .ofEntries (
367+ mapOfEntries (entry ("title" , "1984" ), entry ("author" , "George Orwell" )),
368+ mapOfEntries (entry ("title" , "To Kill a Mockingbird" ), entry ("author" , "Harper Lee" )),
369+ mapOfEntries (
369370 entry ("title" , "The Lord of the Rings" ), entry ("author" , "J.R.R. Tolkien" )));
370371 }
371372
@@ -598,7 +599,7 @@ public void testArithmeticOperations() {
598599 assertThat (waitFor (execute ).getResults ())
599600 .comparingElementsUsing (DATA_CORRESPONDENCE )
600601 .containsExactly (
601- ImmutableMap . ofEntries (
602+ mapOfEntries (
602603 entry ("ratingPlusOne" , 5.2 ),
603604 entry ("yearsSince1900" , 79 ),
604605 entry ("ratingTimesTen" , 42 ),
@@ -652,20 +653,66 @@ public void testChecks() {
652653 randomCol
653654 .pipeline ()
654655 .where (not (Field .of ("rating" ).isNan ()))
655- .select (Field .of ("rating" ).eq (null ).as ("ratingIsNull" ))
656- .select ("title" )
657- .sort (Field .of ("title" ).ascending ())
656+ .select (
657+ Field .of ("rating" ).isNull ().as ("ratingIsNull" ),
658+ Field .of ("rating" ).eq (Constant .nullValue ()).as ("ratingEqNull" ),
659+ not (Field .of ("rating" ).isNan ()).as ("ratingIsNotNan" ))
660+ .limit (1 )
658661 .execute ();
659662 assertThat (waitFor (execute ).getResults ())
660663 .comparingElementsUsing (DATA_CORRESPONDENCE )
661664 .containsExactly (
662- ImmutableMap .of ("title" , "Crime and Punishment" ),
663- ImmutableMap .of ("title" , "Dune" ),
664- ImmutableMap .of ("title" , "Pride and Prejudice" ));
665+ mapOfEntries (
666+ entry ("ratingIsNull" , false ),
667+ entry ("ratingEqNull" , null ),
668+ entry ("ratingIsNotNan" , true )));
669+ }
670+
671+ @ Test
672+ @ Ignore ("Not supported yet" )
673+ public void testLogicalMax () {
674+ Task <PipelineSnapshot > execute =
675+ randomCol
676+ .pipeline ()
677+ .where (Field .of ("author" ).eq ("Douglas Adams" ))
678+ .select (
679+ Field .of ("rating" ).logicalMax (4.5 ).as ("max_rating" ),
680+ logicalMax (Field .of ("published" ), 1900 ).as ("max_published" ))
681+ .execute ();
682+ assertThat (waitFor (execute ).getResults ())
683+ .comparingElementsUsing (DATA_CORRESPONDENCE )
684+ .containsExactly (ImmutableMap .of ("max_rating" , 4.5 , "max_published" , 1979 ));
685+ }
686+
687+ @ Test
688+ @ Ignore ("Not supported yet" )
689+ public void testLogicalMin () {
690+ Task <PipelineSnapshot > execute =
691+ randomCol
692+ .pipeline ()
693+ .select (
694+ Field .of ("rating" ).logicalMin (4.5 ).as ("min_rating" ),
695+ logicalMin (Field .of ("published" ), 1900 ).as ("min_published" ))
696+ .execute ();
697+ assertThat (waitFor (execute ).getResults ())
698+ .comparingElementsUsing (DATA_CORRESPONDENCE )
699+ .containsExactly (ImmutableMap .of ("min_rating" , 4.2 , "min_published" , 1900 ));
665700 }
666701
667702 @ Test
668- public void testMapGet () {}
703+ public void testMapGet () {
704+ Task <PipelineSnapshot > execute =
705+ randomCol
706+ .pipeline ()
707+ .select (Field .of ("awards" ).mapGet ("hugo" ).as ("hugoAward" ), Field .of ("title" ))
708+ .where (eq ("hugoAward" , true ))
709+ .execute ();
710+ assertThat (waitFor (execute ).getResults ())
711+ .comparingElementsUsing (DATA_CORRESPONDENCE )
712+ .containsExactly (
713+ ImmutableMap .of ("hugoAward" , true , "title" , "The Hitchhiker's Guide to the Galaxy" ),
714+ ImmutableMap .of ("hugoAward" , true , "title" , "Dune" ));
715+ }
669716
670717 @ Test
671718 public void testParent () {}
@@ -674,11 +721,81 @@ public void testParent() {}
674721 public void testCollectionId () {}
675722
676723 @ Test
677- public void testDistanceFunctions () {}
724+ public void testDistanceFunctions () {
725+ double [] sourceVector = {0.1 , 0.1 };
726+ double [] targetVector = {0.5 , 0.8 };
727+ Task <PipelineSnapshot > execute =
728+ randomCol
729+ .pipeline ()
730+ .select (
731+ cosineDistance (Constant .vector (sourceVector ), targetVector ).as ("cosineDistance" ),
732+ Function .dotProduct (Constant .vector (sourceVector ), targetVector )
733+ .as ("dotProductDistance" ),
734+ euclideanDistance (Constant .vector (sourceVector ), targetVector )
735+ .as ("euclideanDistance" ))
736+ .limit (1 )
737+ .execute ();
738+ assertThat (waitFor (execute ).getResults ())
739+ .comparingElementsUsing (DATA_CORRESPONDENCE )
740+ .containsExactly (
741+ ImmutableMap .of (
742+ "cosineDistance" , 0.02560880430538015 ,
743+ "dotProductDistance" , 0.13 ,
744+ "euclideanDistance" , 0.806225774829855 ));
745+ }
678746
679747 @ Test
680748 public void testNestedFields () {}
681749
682750 @ Test
683751 public void testMapGetWithFieldNameIncludingNotation () {}
752+
753+ static <T > Map .Entry <String , T > entry (String key , T value ) {
754+ return new Map .Entry <String , T >() {
755+ private String k = key ;
756+ private T v = value ;
757+
758+ @ Override
759+ public String getKey () {
760+ return k ;
761+ }
762+
763+ @ Override
764+ public T getValue () {
765+ return v ;
766+ }
767+
768+ @ Override
769+ public T setValue (T value ) {
770+ T old = v ;
771+ v = value ;
772+ return old ;
773+ }
774+
775+ @ Override
776+ public boolean equals (Object o ) {
777+ if (!(o instanceof Map .Entry )) {
778+ return false ;
779+ }
780+
781+ Map .Entry <?, ?> that = (Map .Entry <?, ?>) o ;
782+ return com .google .common .base .Objects .equal (k , that .getKey ())
783+ && com .google .common .base .Objects .equal (v , that .getValue ());
784+ }
785+
786+ @ Override
787+ public int hashCode () {
788+ return com .google .common .base .Objects .hashCode (k , v );
789+ }
790+ };
791+ }
792+
793+ @ SafeVarargs
794+ static <T > Map <String , T > mapOfEntries (Map .Entry <String , T >... entries ) {
795+ Map <String , T > res = new LinkedHashMap <>();
796+ for (Map .Entry <String , T > entry : entries ) {
797+ res .put (entry .getKey (), entry .getValue ());
798+ }
799+ return Collections .unmodifiableMap (res );
800+ }
684801}
0 commit comments