mirror of
https://github.com/getredash/redash.git
synced 2025-12-19 09:27:23 -05:00
Advanced query search syntax for multi byte search (#7546)
* Advanced query search syntax for multi byte search
* Advanced search for my queries
* Add advanced query seearch tooltip
* Revert "Add advanced query seearch tooltip"
This reverts commit 43148ba6ac.
This commit is contained in:
@@ -2,6 +2,7 @@ import calendar
|
||||
import datetime
|
||||
import logging
|
||||
import numbers
|
||||
import re
|
||||
import time
|
||||
|
||||
import pytz
|
||||
@@ -644,6 +645,43 @@ class Query(ChangeTrackingMixin, TimestampMixin, BelongsToOrgMixin, db.Model):
|
||||
|
||||
return list(outdated_queries.values())
|
||||
|
||||
@classmethod
|
||||
def _do_multi_byte_search(cls, all_queries, term, limit=None):
|
||||
# term examples:
|
||||
# - word
|
||||
# - name:word
|
||||
# - query:word
|
||||
# - "multiple words"
|
||||
# - name:"multiple words"
|
||||
# - word1 word2 word3
|
||||
# - word1 "multiple word" query:"select foo"
|
||||
tokens = re.findall(r'(?:([^:\s]+):)?(?:"([^"]+)"|(\S+))', term)
|
||||
conditions = []
|
||||
for token in tokens:
|
||||
key = None
|
||||
if token[0]:
|
||||
key = token[0]
|
||||
|
||||
if token[1]:
|
||||
value = token[1]
|
||||
else:
|
||||
value = token[2]
|
||||
|
||||
pattern = f"%{value}%"
|
||||
|
||||
if key == "id" and value.isdigit():
|
||||
conditions.append(cls.id.equal(int(value)))
|
||||
elif key == "name":
|
||||
conditions.append(cls.name.ilike(pattern))
|
||||
elif key == "query":
|
||||
conditions.append(cls.query_text.ilike(pattern))
|
||||
elif key == "description":
|
||||
conditions.append(cls.description.ilike(pattern))
|
||||
else:
|
||||
conditions.append(or_(cls.name.ilike(pattern), cls.description.ilike(pattern)))
|
||||
|
||||
return all_queries.filter(and_(*conditions)).order_by(Query.id).limit(limit)
|
||||
|
||||
@classmethod
|
||||
def search(
|
||||
cls,
|
||||
@@ -664,12 +702,7 @@ class Query(ChangeTrackingMixin, TimestampMixin, BelongsToOrgMixin, db.Model):
|
||||
|
||||
if multi_byte_search:
|
||||
# Since tsvector doesn't work well with CJK languages, use `ilike` too
|
||||
pattern = "%{}%".format(term)
|
||||
return (
|
||||
all_queries.filter(or_(cls.name.ilike(pattern), cls.description.ilike(pattern)))
|
||||
.order_by(Query.id)
|
||||
.limit(limit)
|
||||
)
|
||||
return cls._do_multi_byte_search(all_queries, term, limit)
|
||||
|
||||
# sort the result using the weight as defined in the search vector column
|
||||
return all_queries.search(term, sort=True).limit(limit)
|
||||
@@ -678,13 +711,7 @@ class Query(ChangeTrackingMixin, TimestampMixin, BelongsToOrgMixin, db.Model):
|
||||
def search_by_user(cls, term, user, limit=None, multi_byte_search=False):
|
||||
if multi_byte_search:
|
||||
# Since tsvector doesn't work well with CJK languages, use `ilike` too
|
||||
pattern = "%{}%".format(term)
|
||||
return (
|
||||
cls.by_user(user)
|
||||
.filter(or_(cls.name.ilike(pattern), cls.description.ilike(pattern)))
|
||||
.order_by(Query.id)
|
||||
.limit(limit)
|
||||
)
|
||||
return cls._do_multi_byte_search(cls.by_user(user), term, limit)
|
||||
|
||||
return cls.by_user(user).search(term, sort=True).limit(limit)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user