Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comparison operators on indexed+checked attrs #531

Merged
merged 16 commits into from
Nov 25, 2024
Merged

Comparison operators on indexed+checked attrs #531

merged 16 commits into from
Nov 25, 2024

Conversation

dwwoelfel
Copy link
Contributor

@dwwoelfel dwwoelfel commented Nov 22, 2024

Adds $gt, $lt, $gte, and $lte comparison operators for indexed attrs with checked types.

If person.birthdate is an indexed attr typed as a date, you can do something like:

db.useQuery({person: {$: {where: {birthdate: {$gt: new Date(1986, 5, 6)}}}})

How it works
We add new partial indexes on the triples table that extracts the typed data from the json. This is the number index for example:

create index if not exists triples_number_type_idx on triples (
    app_id,
    attr_id,
    triples_extract_number_value(value),
    entity_id
  )
  where ave and checked_data_type = 'number';

Our comparison query uses the index we created:

select * from triples
where app_id = :app_id
  and ave
  and attr_id = :attr_id
  and checked_data_type = 'number'
  and triples_extract_boolean_value(value) > 10;
->  Index Scan using triples_number_type_idx on triples  (cost=0.27..8.30 rows=1 width=143) (actual time=0.027..0.226 rows=221 loops=1)
Index Cond: ((app_id = :app-id)
              AND (attr_id = :attr-id) 
              AND (triples_extract_number_value(value) > '10'::double precision))

For strings, we use a gist index with the pg_trgm extension. It allows us to use the index for like queries and potentially opens up the possibility for doing fuzzy search later.

Other changes

  1. Uses the new type indexes for queries--it should be more efficient than using the regular ave index on json. I wonder if we should disable that index for untyped data.
  2. Validates that the query parameters match the type of the attr. You'll get an error if you try to do:
    {:where {:checkedNumberAttr "string"}}
    

TODOS before deploy:

  • Manually add all of the indexes with create index concurrently so that we don't lock up the db when running the migration
  • Run the migration

Copy link

View Vercel preview at instant-www-js-checked-idxes-jsv.vercel.app.

function matcherForPatternPart(patternPart) {
switch (typeof patternPart) {
case "string":
return patternPart.startsWith("?") ? matchVariable : matchExact;
case "object":
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already do all the filtering in the store, so this saves us an extra comparison on the data.

@@ -57,7 +58,7 @@
(when (seq aggregates)
{:aggregate aggregates}))))

(defn- is-pretty-eq?
(defmacro is-pretty-eq?
Copy link
Contributor Author

@dwwoelfel dwwoelfel Nov 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making this a macro helps jump-to-definition jump to the place is-pretty-eq? is used instead of jumping here.

@dwwoelfel dwwoelfel changed the title [in-progress] Comparison operators on indexed+checked attrs Comparison operators on indexed+checked attrs Nov 25, 2024
Copy link
Contributor

@stopachka stopachka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...This is beautiful!

@dwwoelfel dwwoelfel merged commit 9e4d3bb into main Nov 25, 2024
23 checks passed
@dwwoelfel dwwoelfel deleted the checked-idxes branch November 25, 2024 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants