Skip to content

Commit 18e9224

Browse files
committed
add filtered query test
1 parent cdc3392 commit 18e9224

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

google-cloud-firestore/src/main/java/com/google/cloud/firestore/BasePath.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ boolean isPrefixOf(BasePath<B> path) {
116116
/**
117117
* Compare the current path against another Path object.
118118
*
119-
* <p>The comparison is done segment by segment, with the following rules: 1. Numeric IDs
120-
* (starting with "__id" and ending with "__") are compared numerically. 2. String segments are
121-
* compared lexicographically. 3. Numeric IDs are considered smaller than string segments.
119+
* <p>Compare the current path against another Path object. Paths are compared segment by segment,
120+
* prioritizing numeric IDs (e.g., "__id123__") in ascending order, followed by string segments in
121+
* lexicographical order.
122122
*
123123
* @param other The path to compare to.
124124
* @return -1 if current is less than other, 1 if current greater than other, 0 if equal
@@ -141,26 +141,26 @@ public int compareTo(@Nonnull B other) {
141141
private int compareSegments(String segment1, String segment2) {
142142
// 1. Check if one segment is numeric and the other is not
143143
if (isNumericId(segment1) && !isNumericId(segment2)) {
144-
return -1; // Numeric comes first
144+
return -1;
145145
} else if (!isNumericId(segment1) && isNumericId(segment2)) {
146-
return 1; // String comes later
146+
return 1;
147147
}
148148

149149
// 2. If both are numeric, compare numerically
150150
if (isNumericId(segment1) && isNumericId(segment2)) {
151-
long id1 = extractNumericId(segment1);
152-
long id2 = extractNumericId(segment2);
153-
return Long.compare(id1, id2);
151+
return Long.compare(extractNumericId(segment1), extractNumericId(segment2));
154152
}
155153

156154
// 3. If both are strings, compare lexicographically
157155
return segment1.compareTo(segment2);
158156
}
159157

158+
// Checks if a segment is a numeric ID (starts with "__id" and ends with "__").
160159
private boolean isNumericId(String segment) {
161160
return segment.startsWith("__id") && segment.endsWith("__");
162161
}
163162

163+
// Extracts the numeric value from a numeric ID segment.
164164
private long extractNumericId(String segment) {
165165
return Long.parseLong(segment.substring(4, segment.length() - 2));
166166
}

google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITQueryWatchTest.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.google.cloud.firestore.DocumentReference;
3232
import com.google.cloud.firestore.DocumentSnapshot;
3333
import com.google.cloud.firestore.EventListener;
34+
import com.google.cloud.firestore.FieldPath;
3435
import com.google.cloud.firestore.FieldValue;
3536
import com.google.cloud.firestore.FirestoreException;
3637
import com.google.cloud.firestore.ListenerRegistration;
@@ -647,7 +648,7 @@ public void shutdownNowPreventsAddingNewListener() throws Exception {
647648
}
648649

649650
@Test
650-
public void snapshotListenerSortsDocumentsByDocumentIdInTheSameOrderAsServer() throws Exception {
651+
public void snapshotListenerSortsQueryByDocumentIdInTheSameOrderAsServer() throws Exception {
651652
CollectionReference col = randomColl;
652653

653654
firestore
@@ -690,6 +691,54 @@ public void snapshotListenerSortsDocumentsByDocumentIdInTheSameOrderAsServer() t
690691
assertEquals(expectedOrder, listenerOrder); // Assert order in the SDK
691692
}
692693

694+
@Test
695+
public void snapshotListenerSortsFilteredQueryByDocumentIdInTheSameOrderAsServer()
696+
throws Exception {
697+
CollectionReference col = randomColl;
698+
699+
firestore
700+
.batch()
701+
.set(col.document("A"), Collections.singletonMap("a", 1))
702+
.set(col.document("a"), Collections.singletonMap("a", 1))
703+
.set(col.document("Aa"), Collections.singletonMap("a", 1))
704+
.set(col.document("7"), Collections.singletonMap("a", 1))
705+
.set(col.document("12"), Collections.singletonMap("a", 1))
706+
.set(col.document("__id7__"), Collections.singletonMap("a", 1))
707+
.set(col.document("__id12__"), Collections.singletonMap("a", 1))
708+
.commit()
709+
.get();
710+
711+
Query query =
712+
col.whereGreaterThan(FieldPath.documentId(), "__id7__")
713+
.whereLessThanOrEqualTo(FieldPath.documentId(), "A")
714+
.orderBy("__name__", Direction.ASCENDING);
715+
List<String> expectedOrder = Arrays.asList("__id12__", "12", "7", "A");
716+
717+
QuerySnapshot snapshot = query.get().get();
718+
List<String> queryOrder =
719+
snapshot.getDocuments().stream().map(doc -> doc.getId()).collect(Collectors.toList());
720+
assertEquals(expectedOrder, queryOrder); // Assert order from backend
721+
722+
CountDownLatch latch = new CountDownLatch(1);
723+
List<String> listenerOrder = new ArrayList<>();
724+
725+
ListenerRegistration registration =
726+
query.addSnapshotListener(
727+
(value, error) -> {
728+
listenerOrder.addAll(
729+
value.getDocuments().stream()
730+
.map(doc -> doc.getId())
731+
.collect(Collectors.toList()));
732+
733+
latch.countDown();
734+
});
735+
736+
latch.await();
737+
registration.remove();
738+
739+
assertEquals(expectedOrder, listenerOrder); // Assert order in the SDK
740+
}
741+
693742
/**
694743
* A tuple class used by {@code #queryWatch}. This class represents an event delivered to the
695744
* registered query listener.

0 commit comments

Comments
 (0)