forked from LBRYCommunity/lbry-sdk
claim search uses different tag filtering approaches depeding on query type
This commit is contained in:
parent
c1c7e30ec9
commit
8c878f8e25
2 changed files with 49 additions and 19 deletions
|
@ -35,7 +35,7 @@ STREAM_TYPES = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _apply_constraints_for_array_attributes(constraints, attr, cleaner):
|
def _apply_constraints_for_array_attributes(constraints, attr, cleaner, for_count=False):
|
||||||
any_items = cleaner(constraints.pop(f'any_{attr}s', []))[:ATTRIBUTE_ARRAY_MAX_LENGTH]
|
any_items = cleaner(constraints.pop(f'any_{attr}s', []))[:ATTRIBUTE_ARRAY_MAX_LENGTH]
|
||||||
if any_items:
|
if any_items:
|
||||||
constraints.update({
|
constraints.update({
|
||||||
|
@ -44,8 +44,17 @@ def _apply_constraints_for_array_attributes(constraints, attr, cleaner):
|
||||||
values = ', '.join(
|
values = ', '.join(
|
||||||
f':$any_{attr}{i}' for i in range(len(any_items))
|
f':$any_{attr}{i}' for i in range(len(any_items))
|
||||||
)
|
)
|
||||||
|
if for_count:
|
||||||
constraints[f'claim.claim_hash__in#_any_{attr}'] = f"""
|
constraints[f'claim.claim_hash__in#_any_{attr}'] = f"""
|
||||||
SELECT DISTINCT claim_hash FROM {attr} WHERE {attr} IN ({values})
|
SELECT claim_hash FROM {attr} WHERE {attr} IN ({values})
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
constraints[f'#_any_{attr}'] = f"""
|
||||||
|
EXISTS(
|
||||||
|
SELECT 1 FROM {attr} WHERE
|
||||||
|
claim.claim_hash={attr}.claim_hash
|
||||||
|
AND {attr} IN ({values})
|
||||||
|
)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
all_items = cleaner(constraints.pop(f'all_{attr}s', []))[:ATTRIBUTE_ARRAY_MAX_LENGTH]
|
all_items = cleaner(constraints.pop(f'all_{attr}s', []))[:ATTRIBUTE_ARRAY_MAX_LENGTH]
|
||||||
|
@ -57,10 +66,19 @@ def _apply_constraints_for_array_attributes(constraints, attr, cleaner):
|
||||||
values = ', '.join(
|
values = ', '.join(
|
||||||
f':$all_{attr}{i}' for i in range(len(all_items))
|
f':$all_{attr}{i}' for i in range(len(all_items))
|
||||||
)
|
)
|
||||||
|
if for_count:
|
||||||
constraints[f'claim.claim_hash__in#_all_{attr}'] = f"""
|
constraints[f'claim.claim_hash__in#_all_{attr}'] = f"""
|
||||||
SELECT claim_hash FROM {attr} WHERE {attr} IN ({values})
|
SELECT claim_hash FROM {attr} WHERE {attr} IN ({values})
|
||||||
GROUP BY claim_hash HAVING COUNT({attr}) = :$all_{attr}_count
|
GROUP BY claim_hash HAVING COUNT({attr}) = :$all_{attr}_count
|
||||||
"""
|
"""
|
||||||
|
else:
|
||||||
|
constraints[f'#_all_{attr}'] = f"""
|
||||||
|
{len(all_items)}=(
|
||||||
|
SELECT count(*) FROM {attr} WHERE
|
||||||
|
claim.claim_hash={attr}.claim_hash
|
||||||
|
AND {attr} IN ({values})
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
not_items = cleaner(constraints.pop(f'not_{attr}s', []))[:ATTRIBUTE_ARRAY_MAX_LENGTH]
|
not_items = cleaner(constraints.pop(f'not_{attr}s', []))[:ATTRIBUTE_ARRAY_MAX_LENGTH]
|
||||||
if not_items:
|
if not_items:
|
||||||
|
@ -70,8 +88,17 @@ def _apply_constraints_for_array_attributes(constraints, attr, cleaner):
|
||||||
values = ', '.join(
|
values = ', '.join(
|
||||||
f':$not_{attr}{i}' for i in range(len(not_items))
|
f':$not_{attr}{i}' for i in range(len(not_items))
|
||||||
)
|
)
|
||||||
|
if for_count:
|
||||||
constraints[f'claim.claim_hash__not_in#_not_{attr}'] = f"""
|
constraints[f'claim.claim_hash__not_in#_not_{attr}'] = f"""
|
||||||
SELECT DISTINCT claim_hash FROM {attr} WHERE {attr} IN ({values})
|
SELECT claim_hash FROM {attr} WHERE {attr} IN ({values})
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
constraints[f'#_not_{attr}'] = f"""
|
||||||
|
NOT EXISTS(
|
||||||
|
SELECT 1 FROM {attr} WHERE
|
||||||
|
claim.claim_hash={attr}.claim_hash
|
||||||
|
AND {attr} IN ({values})
|
||||||
|
)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -745,7 +772,7 @@ class SQLDB:
|
||||||
r(self.update_claimtrie, height, recalculate_claim_hashes, deleted_claim_names, forward_timer=True)
|
r(self.update_claimtrie, height, recalculate_claim_hashes, deleted_claim_names, forward_timer=True)
|
||||||
r(calculate_trending, self.db, height, self.main.first_sync, daemon_height)
|
r(calculate_trending, self.db, height, self.main.first_sync, daemon_height)
|
||||||
|
|
||||||
def get_claims(self, cols, join=True, **constraints):
|
def get_claims(self, cols, for_count=False, **constraints):
|
||||||
if 'order_by' in constraints:
|
if 'order_by' in constraints:
|
||||||
sql_order_by = []
|
sql_order_by = []
|
||||||
for order_by in constraints['order_by']:
|
for order_by in constraints['order_by']:
|
||||||
|
@ -776,7 +803,7 @@ class SQLDB:
|
||||||
|
|
||||||
if constraints.pop('is_controlling', False):
|
if constraints.pop('is_controlling', False):
|
||||||
if {'sequence', 'amount_order'}.isdisjoint(constraints):
|
if {'sequence', 'amount_order'}.isdisjoint(constraints):
|
||||||
join = True
|
for_count = False
|
||||||
constraints['claimtrie.claim_hash__is_not_null'] = ''
|
constraints['claimtrie.claim_hash__is_not_null'] = ''
|
||||||
if 'sequence' in constraints:
|
if 'sequence' in constraints:
|
||||||
constraints['order_by'] = 'claim.activation_height ASC'
|
constraints['order_by'] = 'claim.activation_height ASC'
|
||||||
|
@ -864,14 +891,14 @@ class SQLDB:
|
||||||
if 'fee_currency' in constraints:
|
if 'fee_currency' in constraints:
|
||||||
constraints['claim.fee_currency'] = constraints.pop('fee_currency').lower()
|
constraints['claim.fee_currency'] = constraints.pop('fee_currency').lower()
|
||||||
|
|
||||||
_apply_constraints_for_array_attributes(constraints, 'tag', clean_tags)
|
_apply_constraints_for_array_attributes(constraints, 'tag', clean_tags, for_count)
|
||||||
_apply_constraints_for_array_attributes(constraints, 'language', lambda _: _)
|
_apply_constraints_for_array_attributes(constraints, 'language', lambda _: _, for_count)
|
||||||
_apply_constraints_for_array_attributes(constraints, 'location', lambda _: _)
|
_apply_constraints_for_array_attributes(constraints, 'location', lambda _: _, for_count)
|
||||||
|
|
||||||
select = f"SELECT {cols} FROM claim"
|
select = f"SELECT {cols} FROM claim"
|
||||||
|
|
||||||
sql, values = query(
|
sql, values = query(
|
||||||
select if not join else select+"""
|
select if for_count else select+"""
|
||||||
LEFT JOIN claimtrie USING (claim_hash)
|
LEFT JOIN claimtrie USING (claim_hash)
|
||||||
LEFT JOIN claim as channel ON (claim.channel_hash=channel.claim_hash)
|
LEFT JOIN claim as channel ON (claim.channel_hash=channel.claim_hash)
|
||||||
""", **constraints
|
""", **constraints
|
||||||
|
@ -886,7 +913,7 @@ class SQLDB:
|
||||||
constraints.pop('offset', None)
|
constraints.pop('offset', None)
|
||||||
constraints.pop('limit', None)
|
constraints.pop('limit', None)
|
||||||
constraints.pop('order_by', None)
|
constraints.pop('order_by', None)
|
||||||
count = self.get_claims('count(*)', join=False, **constraints)
|
count = self.get_claims('count(*)', for_count=True, **constraints)
|
||||||
return count[0][0]
|
return count[0][0]
|
||||||
|
|
||||||
def _search(self, **constraints):
|
def _search(self, **constraints):
|
||||||
|
|
|
@ -93,7 +93,10 @@ def constraints_to_sql(constraints, joiner=' AND ', prepend_key=''):
|
||||||
if '#' in key:
|
if '#' in key:
|
||||||
key, tag = key[:key.index('#')], key[key.index('#')+1:]
|
key, tag = key[:key.index('#')], key[key.index('#')+1:]
|
||||||
col, op, key = key, '=', key.replace('.', '_')
|
col, op, key = key, '=', key.replace('.', '_')
|
||||||
if key.startswith('$'):
|
if not key:
|
||||||
|
sql.append(constraint)
|
||||||
|
continue
|
||||||
|
elif key.startswith('$'):
|
||||||
values[key] = constraint
|
values[key] = constraint
|
||||||
continue
|
continue
|
||||||
elif key.endswith('__not'):
|
elif key.endswith('__not'):
|
||||||
|
|
Loading…
Reference in a new issue