isar-community / isar

Extremely fast, easy to use, and fully async NoSQL database for Flutter
https://isar-community.dev
Apache License 2.0
126 stars 14 forks source link

[v4] Query grouping bug #92

Open nikobe5545 opened 2 months ago

nikobe5545 commented 2 months ago

When creating query groups directly after the where-directive the groups are not created correctly, but if adding some dummy filter before adding groups it works as expected (examples below).

Steps to Reproduce

In my case I have a collection of products with name and brand (and some other fields). I have a use-case where I want to search for a tokenised string, for instance "first second" and look for matches in either name or brand for each word in the string.

The idea was to create an Isar query that resembles the following pseudo SQL:

WHERE
(name CONTAINS 'first' OR brand CONTAINS 'first')
AND
(name CONTAINS 'second' OR brand CONTAINS 'second')

The generated query however is equivalent to the following pseudo SQL:

WHERE
name CONTAINS 'first'
OR (
  brand CONTAINS 'first'
  AND (
    name CONTAINS 'second'
    OR brand CONTAINS 'second'
  )
)

Code sample

Code that does not give the expected result:

final result = isar.products
        .where()
        .group((q) => q.nameContains('first').or().brandContains('first'))
        .and()
        .group((q) => q.nameContains('second').or().brandContains('second'))
        .findAll();

Workaround (note the added nameIsNotEmpty()):

final result = isar.products
        .where()
        .nameIsNotEmpty()
        .group((q) => q.nameContains('first').or().brandContains('first'))
        .and()
        .group((q) => q.nameContains('second').or().brandContains('second'))
        .findAll();

In my case it was easy to create the workaround because the name will never be empty, so it's like adding a 1 = 1 in SQL.

Details