Skip to content

Commit c2300b5

Browse files
NicolappsConvex, Inc.
authored andcommitted
Fix search clauses to use JSON-serialized values (#40941)
GitOrigin-RevId: edfe7005d54a5210db8bce566d9ba24e4b598310
1 parent 2364339 commit c2300b5

File tree

3 files changed

+108
-19
lines changed

3 files changed

+108
-19
lines changed

npm-packages/dashboard-common/src/features/data/components/DataFilters/IndexFilters.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
MagnifyingGlassIcon,
88
} from "@radix-ui/react-icons";
99
import { GenericDocument } from "convex/server";
10-
import { ValidatorJSON } from "convex/values";
10+
import { convexToJson, ValidatorJSON } from "convex/values";
1111
import {
1212
DatabaseIndexFilter,
1313
FilterByIndexRange,
@@ -227,7 +227,10 @@ export function IndexFilters({
227227
clauses: option.fields.map((field: string) => ({
228228
field,
229229
enabled: false,
230-
value: defaultDocument[field],
230+
value:
231+
defaultDocument[field] === undefined
232+
? undefined
233+
: convexToJson(defaultDocument[field]),
231234
})),
232235
} satisfies SearchIndexFilter,
233236
}

npm-packages/system-udfs/convex/_system/frontend/lib/filters.test.ts

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, test, expect, it } from "vitest";
2-
import { GenericDocument } from "convex/server";
2+
import { GenericDocument, SearchIndex } from "convex/server";
33
import {
44
Filter,
55
FilterByIndex,
@@ -21,7 +21,6 @@ import {
2121
validateIndexFilter,
2222
validateSearchIndexFilter,
2323
} from "./filters";
24-
import { SearchIndex } from "../../../../../convex/dist/internal-cjs-types/server";
2524

2625
const samplePage: GenericDocument[] = [
2726
{ variableType: "stringValue" },
@@ -572,6 +571,86 @@ describe("filters", () => {
572571
]);
573572
});
574573

574+
it("should apply search index filters with undefined values", () => {
575+
const mockBuilder = new MockSearchBuilder();
576+
const searchString = "test search";
577+
const searchIndexFilters = [
578+
{ field: "organizationId", enabled: true, value: undefined },
579+
];
580+
const selectedIndex: SearchIndex = {
581+
indexDescriptor: "testSearchIndex",
582+
searchField: "description",
583+
filterFields: ["userId", "organizationId"],
584+
};
585+
586+
applySearchIndexFilters(
587+
mockBuilder as any,
588+
searchString,
589+
searchIndexFilters,
590+
selectedIndex,
591+
);
592+
593+
expect(mockBuilder.operations).toEqual([
594+
{ op: "search", field: "description", value: "test search" },
595+
{ op: "eq", field: "organizationId", value: undefined },
596+
]);
597+
});
598+
599+
it("should apply search index filters with JSON-serialized values", () => {
600+
const mockBuilder = new MockSearchBuilder();
601+
const searchString = "test search";
602+
const searchIndexFilters = [
603+
{ field: "userId", enabled: true, value: { $integer: "AQAAAAAAAAA=" } },
604+
];
605+
const selectedIndex: SearchIndex = {
606+
indexDescriptor: "testSearchIndex",
607+
searchField: "description",
608+
filterFields: ["userId", "organizationId"],
609+
};
610+
611+
applySearchIndexFilters(
612+
mockBuilder as any,
613+
searchString,
614+
searchIndexFilters,
615+
selectedIndex,
616+
);
617+
618+
expect(mockBuilder.operations).toEqual([
619+
{ op: "search", field: "description", value: "test search" },
620+
{ op: "eq", field: "userId", value: BigInt(1) },
621+
]);
622+
});
623+
624+
it("should apply search index filters with value = undefined", () => {
625+
const mockBuilder = new MockSearchBuilder();
626+
const searchString = "test search";
627+
const searchIndexFilters = [
628+
{
629+
field: "userId",
630+
enabled: true,
631+
value:
632+
"__CONVEX_PLACEHOLDER_undefined_I23atX0jcndVbFgXoQZffsih7eAqktCyFjgUuAeNBtfr3ySOljPSPSEOPFgprkdBO3zXNiGEJxmJ5ZFPc5C5qKesG80QRPvlJe8vgSxAt9feLTwxTg4PHfVwUaTEJU67FDwldWmTxp1guMPwxQ2jOuhEryTBf3mQ",
633+
},
634+
];
635+
const selectedIndex: SearchIndex = {
636+
indexDescriptor: "testSearchIndex",
637+
searchField: "description",
638+
filterFields: ["userId", "organizationId"],
639+
};
640+
641+
applySearchIndexFilters(
642+
mockBuilder as any,
643+
searchString,
644+
searchIndexFilters,
645+
selectedIndex,
646+
);
647+
648+
expect(mockBuilder.operations).toEqual([
649+
{ op: "search", field: "description", value: "test search" },
650+
{ op: "eq", field: "userId", value: undefined },
651+
]);
652+
});
653+
575654
it("should only apply filters for fields that exist in the filter", () => {
576655
const mockBuilder = new MockSearchBuilder();
577656
const searchString = "test search";
@@ -782,7 +861,7 @@ describe("filters", () => {
782861
const result = validateSearchIndexFilter(
783862
indexName,
784863
[
785-
{ field: "userId", enabled: true, value: BigInt(123) },
864+
{ field: "userId", enabled: true, value: 123 },
786865
{ field: "organization", enabled: true, value: "exampleOrg" },
787866
],
788867
selectedIndex,
@@ -818,7 +897,7 @@ describe("filters", () => {
818897
const result = validateSearchIndexFilter(
819898
indexName,
820899
[
821-
{ field: "userId", enabled: true, value: BigInt(123) },
900+
{ field: "userId", enabled: true, value: 123 },
822901
{ field: "organization", enabled: true, value: "exampleOrg" },
823902
],
824903
selectedIndex,
@@ -842,7 +921,7 @@ describe("filters", () => {
842921
const result = validateSearchIndexFilter(
843922
indexName,
844923
[
845-
{ field: "userId", enabled: true, value: BigInt(123) },
924+
{ field: "userId", enabled: true, value: 123 },
846925
{ field: "organization", enabled: false, value: "exampleOrg" },
847926
],
848927
selectedIndex,
@@ -889,8 +968,8 @@ describe("filters", () => {
889968
const result = validateSearchIndexFilter(
890969
indexName,
891970
[
892-
{ field: "userId", enabled: true, value: BigInt(123) },
893-
{ field: "userId", enabled: true, value: BigInt(123) },
971+
{ field: "userId", enabled: true, value: 123 },
972+
{ field: "userId", enabled: true, value: 123 },
894973
],
895974
selectedIndex,
896975
"asc",
@@ -912,8 +991,8 @@ describe("filters", () => {
912991
const result = validateSearchIndexFilter(
913992
indexName,
914993
[
915-
{ field: "userId", enabled: true, value: BigInt(123) },
916-
{ field: "userId", enabled: false, value: BigInt(456) },
994+
{ field: "userId", enabled: true, value: 123 },
995+
{ field: "userId", enabled: false, value: 456 },
917996
],
918997
selectedIndex,
919998
"asc",

npm-packages/system-udfs/convex/_system/frontend/lib/filters.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ export type SearchIndexFilter = {
2929
name: string;
3030
search: string;
3131
/** The clauses on the filter fields of the search index */
32-
clauses: {
33-
field: string;
34-
enabled: boolean;
35-
value: Value;
36-
}[];
32+
clauses: SearchIndexFilterClause[];
33+
};
34+
35+
export type SearchIndexFilterClause = {
36+
field: string;
37+
enabled: boolean;
38+
value: JSONValue | undefined;
3739
};
3840

3941
export type FilterCommon = {
@@ -362,15 +364,20 @@ export function applySearchIndexFilters<
362364
>(
363365
q: SearchFilterBuilder<Document, SearchIndexConfig>,
364366
search: string,
365-
filters: Array<{ field: string; enabled: boolean; value: Value }>,
367+
filters: SearchIndexFilterClause[],
366368
selectedIndex: SearchIndex,
367369
): SearchFilterFinalizer<Document, SearchIndexConfig> {
368370
let builder = q.search(selectedIndex.searchField, search);
369371

370372
// Apply filters
371373
for (const { field, enabled, value } of filters) {
372374
if (enabled) {
373-
builder = builder.eq(field, value as any);
375+
builder = builder.eq(
376+
field,
377+
(value === UNDEFINED_PLACEHOLDER
378+
? undefined
379+
: jsonToConvexOrValue(value)) as any,
380+
);
374381
}
375382
}
376383

@@ -452,7 +459,7 @@ export function validateIndexFilter(
452459
*/
453460
export function validateSearchIndexFilter(
454461
indexName: string,
455-
filters: Array<{ field: string; enabled: boolean; value: Value }>,
462+
filters: SearchIndexFilterClause[],
456463
selectedIndex: Index | SearchIndex | undefined,
457464
order: "asc" | "desc",
458465
) {

0 commit comments

Comments
 (0)