server/tags: reduce number of queries
On a test page with 50 tags, 158 queries were reduced to 3: 1. Get the authenticated user 2. Get tags for given page 3. Count all tags Looks just about right.
This commit is contained in:
parent
d813601d92
commit
339c9a3333
8 changed files with 33 additions and 17 deletions
|
@ -11,9 +11,12 @@ class BaseSearchConfig(object):
|
|||
SORT_DESC = -1
|
||||
SORT_ASC = 1
|
||||
|
||||
def create_query(self):
|
||||
def create_filter_query(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def create_count_query(self):
|
||||
return self.create_filter_query()
|
||||
|
||||
@property
|
||||
def anonymous_filter(self):
|
||||
return None
|
||||
|
|
|
@ -3,7 +3,7 @@ from szurubooru import db
|
|||
from szurubooru.search.base_search_config import BaseSearchConfig
|
||||
|
||||
class CommentSearchConfig(BaseSearchConfig):
|
||||
def create_query(self):
|
||||
def create_filter_query(self):
|
||||
return db.session.query(db.Comment).join(db.User)
|
||||
|
||||
def finalize_query(self, query):
|
||||
|
|
|
@ -22,7 +22,7 @@ def _type_transformer(value):
|
|||
value, available_types))
|
||||
|
||||
class PostSearchConfig(BaseSearchConfig):
|
||||
def create_query(self):
|
||||
def create_filter_query(self):
|
||||
return db.session.query(db.Post)
|
||||
|
||||
def finalize_query(self, query):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import re
|
||||
import sqlalchemy
|
||||
from szurubooru import errors
|
||||
from szurubooru import db, errors
|
||||
from szurubooru.search import criteria
|
||||
|
||||
class SearchExecutor(object):
|
||||
|
@ -17,15 +17,22 @@ class SearchExecutor(object):
|
|||
Parse input and return tuple containing total record count and filtered
|
||||
entities.
|
||||
'''
|
||||
filter_query = self._prepare(query_text)
|
||||
filter_query = self.config.create_filter_query()
|
||||
filter_query = filter_query.options(sqlalchemy.orm.lazyload('*'))
|
||||
filter_query = self._prepare(filter_query, query_text)
|
||||
entities = filter_query \
|
||||
.offset((page - 1) * page_size).limit(page_size).all()
|
||||
count_query = filter_query.statement \
|
||||
.offset((page - 1) * page_size) \
|
||||
.limit(page_size) \
|
||||
.all()
|
||||
|
||||
count_query = self.config.create_count_query()
|
||||
count_query = count_query.options(sqlalchemy.orm.lazyload('*'))
|
||||
count_query = self._prepare(count_query, query_text)
|
||||
count_statement = count_query \
|
||||
.statement \
|
||||
.with_only_columns([sqlalchemy.func.count()]) \
|
||||
.order_by(None)
|
||||
count = filter_query.session \
|
||||
.execute(count_query) \
|
||||
.scalar()
|
||||
count = db.session.execute(count_statement).scalar()
|
||||
return (count, entities)
|
||||
|
||||
def execute_and_serialize(self, ctx, serializer):
|
||||
|
@ -41,10 +48,8 @@ class SearchExecutor(object):
|
|||
'results': [serializer(entity) for entity in entities],
|
||||
}
|
||||
|
||||
def _prepare(self, query_text):
|
||||
def _prepare(self, query, query_text):
|
||||
''' Parse input and return SQLAlchemy query. '''
|
||||
query = self.config.create_query() \
|
||||
.options(sqlalchemy.orm.lazyload('*'))
|
||||
for token in re.split(r'\s+', (query_text or '').lower()):
|
||||
if not token:
|
||||
continue
|
||||
|
|
|
@ -2,7 +2,7 @@ from szurubooru import db
|
|||
from szurubooru.search.base_search_config import BaseSearchConfig
|
||||
|
||||
class SnapshotSearchConfig(BaseSearchConfig):
|
||||
def create_query(self):
|
||||
def create_filter_query(self):
|
||||
return db.session.query(db.Snapshot)
|
||||
|
||||
def finalize_query(self, query):
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.sql.expression import func
|
||||
from szurubooru import db
|
||||
from szurubooru.search.base_search_config import BaseSearchConfig
|
||||
|
||||
class TagSearchConfig(BaseSearchConfig):
|
||||
def create_query(self):
|
||||
def create_filter_query(self):
|
||||
return self.create_count_query().options(
|
||||
joinedload(db.Tag.names),
|
||||
joinedload(db.Tag.category),
|
||||
joinedload(db.Tag.suggestions).joinedload(db.Tag.names),
|
||||
joinedload(db.Tag.implications).joinedload(db.Tag.names)
|
||||
)
|
||||
|
||||
def create_count_query(self):
|
||||
return db.session.query(db.Tag)
|
||||
|
||||
def finalize_query(self, query):
|
||||
|
|
|
@ -5,7 +5,7 @@ from szurubooru.search.base_search_config import BaseSearchConfig
|
|||
class UserSearchConfig(BaseSearchConfig):
|
||||
''' Executes searches related to the users. '''
|
||||
|
||||
def create_query(self):
|
||||
def create_filter_query(self):
|
||||
return db.session.query(db.User)
|
||||
|
||||
def finalize_query(self, query):
|
||||
|
|
|
@ -56,7 +56,6 @@ def verify_unpaged(executor):
|
|||
actual_count, actual_posts = executor.execute(
|
||||
input, page=1, page_size=100)
|
||||
actual_post_ids = list([p.post_id for p in actual_posts])
|
||||
print(actual_post_ids, expected_post_ids)
|
||||
assert actual_count == len(expected_post_ids)
|
||||
if not test_order:
|
||||
actual_post_ids = sorted(actual_post_ids)
|
||||
|
|
Loading…
Reference in a new issue