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

Replace btree with btree_gin indexes for PostgreSQL to allow larger metadata and faster nested search #588

Merged
merged 14 commits into from
Nov 14, 2023
Merged
13 changes: 11 additions & 2 deletions tiled/catalog/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import shutil
import sys
import uuid
from functools import partial
from functools import partial, reduce
from pathlib import Path
from urllib.parse import quote_plus, urlparse

Expand Down Expand Up @@ -938,9 +938,18 @@ def _prepare_structure(structure_family, structure):

def binary_op(query, tree, operation):
dialect_name = tree.engine.url.get_dialect().name
attr = orm.Node.metadata_[query.key.split(".")]
keys = query.key.split(".")
attr = orm.Node.metadata_[keys]
if dialect_name == "sqlite":
condition = operation(_get_value(attr, type(query.value)), query.value)
# specific case where GIN optomized index can be used to speed up POSTGRES equals queries
elif dialect_name == "postgresql" and operation == operator.eq:
Kezzsim marked this conversation as resolved.
Show resolved Hide resolved
condition = orm.Node.metadata_.op("@>")(
type_coerce(
{keys[0]: reduce(lambda x, y: {y: x}, keys[1:][::-1], query.value)},
Copy link
Member

Choose a reason for hiding this comment

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

Clever. Can you refactor this into a utility function so that it can be precisely targeted with a unit test? It might also end up being reused in the future, elsewhere.

orm.Node.metadata_.type,
)
)
else:
condition = operation(attr, type_coerce(query.value, orm.Node.metadata_.type))
return tree.new_variation(conditions=tree.conditions + [condition])
Expand Down
3 changes: 3 additions & 0 deletions tiled/catalog/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ async def initialize_database(engine):
from . import orm # noqa: F401

async with engine.connect() as connection:
# Install extensions
if engine.dialect.name == "postgresql":
await connection.execute(text("create extension btree_gin;"))
# Create all tables.
await connection.run_sync(Base.metadata.create_all)
if engine.dialect.name == "sqlite":
Expand Down
2 changes: 1 addition & 1 deletion tiled/catalog/orm.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class Node(Timestamped, Base):
"time_created",
"id",
"metadata",
postgresql_using="btree",
postgresql_using="gin",
),
# This is used by ORDER BY with the default sorting.
# Index("ancestors_time_created", "ancestors", "time_created"),
Expand Down