diff --git a/packages/backend-core/src/db/lucene.ts b/packages/backend-core/src/db/lucene.ts index d9dddd0097..09d0224014 100644 --- a/packages/backend-core/src/db/lucene.ts +++ b/packages/backend-core/src/db/lucene.ts @@ -432,9 +432,25 @@ export class QueryBuilder { } if (this.#query.empty) { build(this.#query.empty, (key: string) => `(*:* -${key}:["" TO *])`) + + // Because the structure of an empty filter looks like this: + // { empty: { someKey: null } } + // + // The check inside of `build` does not set `allFiltersEmpty`, which results + // in weird behaviour when the empty filter is the only filter. We get around + // this by setting `allFiltersEmpty` to false here. + allFiltersEmpty = false } if (this.#query.notEmpty) { build(this.#query.notEmpty, (key: string) => `${key}:["" TO *]`) + + // Because the structure of a notEmpty filter looks like this: + // { notEmpty: { someKey: null } } + // + // The check inside of `build` does not set `allFiltersEmpty`, which results + // in weird behaviour when the empty filter is the only filter. We get around + // this by setting `allFiltersEmpty` to false here. + allFiltersEmpty = false } if (this.#query.oneOf) { build(this.#query.oneOf, oneOf) diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index 6ab7ac61d4..9e1511105d 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -252,6 +252,31 @@ describe.each([ }).toFindNothing()) }) + describe("empty", () => { + it("finds no empty rows", () => + expectQuery({ empty: { name: null } }).toFindNothing()) + + it("should not be affected by when filter empty behaviour", () => + expectQuery({ + empty: { name: null }, + onEmptyFilter: EmptyFilterOption.RETURN_ALL, + }).toFindNothing()) + }) + + describe("notEmpty", () => { + it("finds all non-empty rows", () => + expectQuery({ notEmpty: { name: null } }).toContainExactly([ + { name: "foo" }, + { name: "bar" }, + ])) + + it("should not be affected by when filter empty behaviour", () => + expectQuery({ + notEmpty: { name: null }, + onEmptyFilter: EmptyFilterOption.RETURN_NONE, + }).toContainExactly([{ name: "foo" }, { name: "bar" }])) + }) + describe("sort", () => { it("sorts ascending", () => expectSearch({