@lotics/app-sdk 0.64.0 → 0.64.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/queries.md +18 -7
- package/package.json +1 -1
package/docs/queries.md
CHANGED
|
@@ -431,7 +431,7 @@ derived surfaces share one implementation.
|
|
|
431
431
|
|
|
432
432
|
| Field type | Column type | Source-layer operators | Derived-layer differences | Sort / group / aggregate notes |
|
|
433
433
|
| --- | --- | --- | --- | --- |
|
|
434
|
-
| text | `text` | `equals`, `not_equals`, `contains`, `does_not_contain`, `starts_with`, `ends_with`, `is_empty`, `is_not_empty`, `is_any_of`, `is_none_of` | same set | Sort is lexicographic in the database's default collation — no locale control. Text comparisons normalize both sides (trim + case-insensitive). |
|
|
434
|
+
| text | `text` | `equals`, `not_equals`, `contains`, `does_not_contain`, `starts_with`, `ends_with`, `is_empty`, `is_not_empty`, `is_any_of`, `is_none_of` | same set | Sort is lexicographic in the database's default collation — no locale control. Text comparisons normalize both sides (trim + case-insensitive). The LIKE family (`contains`, `does_not_contain`, `starts_with`, `ends_with`) additionally folds **diacritics**, so `contains "ha noi"` matches `"Hà Nội"`; the identity operators (`equals`, `not_equals`, `is_any_of`, `is_none_of`) do **not** — they compare a stored value, and `mã` is not `ma`. |
|
|
435
435
|
| number | `number` | `equals`, `not_equals`, `greater_than`, `less_than`, `greater_than_or_equal_to`, `less_than_or_equal_to`, `is_empty`, `is_not_empty` | same set | Full numeric aggregate set (§8). |
|
|
436
436
|
| date / datetime | `date` / `datetime` (datetime when the field's format includes time) | `on`, `before`, `after`, `on_or_before`, `on_or_after`, `between`, `time_of_day`, `is_empty`, `is_not_empty` — values are `DateTimePoint`s (below) | same set | Day-level filters on datetime values expand to the full-day window. Sortable; bucketable in `group.by` (§8); `earliest`/`latest`/`min`/`max`/`date_range` aggregate. |
|
|
437
437
|
| boolean | `boolean` | `equals` (value `true`/`false`; `false` matches NULL/missing) | same | `checked`/`unchecked`/`percent_*` aggregate (`unchecked` counts false **or** empty). |
|
|
@@ -596,11 +596,20 @@ It AND-s with `filter` (search *within* a scope) and is templatable
|
|
|
596
596
|
(`"search": "{{params.q}}"`). An empty or whitespace-only term matches everything; an
|
|
597
597
|
unresolved optional token prunes to match-all (§6).
|
|
598
598
|
|
|
599
|
-
**Search-as-you-type uses `search`, never a `contains` OR-group.** Per-field
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
599
|
+
**Search-as-you-type over a LARGE table uses `search`, never a `contains` OR-group.** Per-field
|
|
600
|
+
`contains` is unindexed — a zero-match keystroke forces a full-partition scan that hangs the
|
|
601
|
+
picker. (It is not accent-sensitive; the LIKE family folds diacritics, §5.) Gate the fetch on a
|
|
602
|
+
non-empty term client-side (`enabled`), or first paint dumps the table.
|
|
603
|
+
|
|
604
|
+
**But `search` matches the WHOLE record, and on an identity box that is usually wrong.** The
|
|
605
|
+
search document indexes select option labels, member names, dates in three formats, and each
|
|
606
|
+
linked record's cached display text — including the `Field=True/False` pill a boolean renders
|
|
607
|
+
into. A box captioned "find a person" then matches rows that merely share a stage label or an
|
|
608
|
+
owner, and folding makes near-homographs collide (`tiến` ≡ `tiền`). Measured on a real 88-row
|
|
609
|
+
customer book, one such term returned **every row**. When the box means *find this person*, bound
|
|
610
|
+
it: an OR-group of `contains` over the two or three identity fields (name, national id, phone),
|
|
611
|
+
with the term param `required: false` so an empty box prunes the group to match-all. Use `search`
|
|
612
|
+
when the box genuinely means *find this anywhere in the record*.
|
|
604
613
|
|
|
605
614
|
---
|
|
606
615
|
|
|
@@ -872,7 +881,9 @@ and is not — and a playbook rule applied to the wrong query costs effort while
|
|
|
872
881
|
### The authoring rules
|
|
873
882
|
|
|
874
883
|
1. **Filter at the source.** Push every static predicate into `from_table.filter`.
|
|
875
|
-
2. **
|
|
884
|
+
2. **Match the operator to what the box MEANS.** *Find this anywhere in the record* → `search`.
|
|
885
|
+
*Find this person/order* → a `contains` OR-group over the identity fields (§7) — the
|
|
886
|
+
whole-record index will surface rows that only share an owner or a status.
|
|
876
887
|
3. **Aggregate and bucket server-side.** A dashboard reads grouped rows, never raw rows it
|
|
877
888
|
reduces in JS — raw-row shipping burns the 10k cap, the timeout, and bandwidth at once.
|
|
878
889
|
4. **Project narrow.** Every un-rendered column is wasted bytes; every un-rendered `files`
|