Skip to content
Snippets Groups Projects
Commit 15997c8c authored by Tanner Prestegard's avatar Tanner Prestegard Committed by GraceDB
Browse files

Minor search backend enhancements

parent ffa70e62
No related branches found
No related tags found
No related merge requests found
...@@ -22,7 +22,7 @@ from django.db.models.query import QuerySet ...@@ -22,7 +22,7 @@ from django.db.models.query import QuerySet
# (weak) natural language time parsing. # (weak) natural language time parsing.
from events.nltime import nlTimeExpression as nltime_ from events.nltime import nlTimeExpression as nltime_
nltime = nltime_.setParseAction(lambda toks: toks["calculatedTime"]) nltime = nltime_.setParseAction(lambda toks: toks["calculatedTime"])
from events.models import Group, Pipeline, Search, Label from events.models import Group, Pipeline, Search
from .labels import getLabelQ from .labels import getLabelQ
from .superevents import parse_superevent_id, superevent_expr from .superevents import parse_superevent_id, superevent_expr
from ..constants import RUN_MAP, ExpressionOperator from ..constants import RUN_MAP, ExpressionOperator
...@@ -252,7 +252,7 @@ def parseQuery(s): ...@@ -252,7 +252,7 @@ def parseQuery(s):
# Analysis Groups # Analysis Groups
# XXX Querying the database at module compile time is a bad idea! # XXX Querying the database at module compile time is a bad idea!
# See: https://docs.djangoproject.com/en/1.8/topics/testing/overview/ # See: https://docs.djangoproject.com/en/1.8/topics/testing/overview/
groupNames = [group.name for group in Group.objects.all()] groupNames = list(Group.objects.values_list('name', flat=True))
group = Or(map(CaselessLiteral, groupNames)).setName("analysis group name") group = Or(map(CaselessLiteral, groupNames)).setName("analysis group name")
#groupList = delimitedList(group, delim='|').setName("analysis group list") #groupList = delimitedList(group, delim='|').setName("analysis group list")
groupList = OneOrMore(group).setName("analysis group list") groupList = OneOrMore(group).setName("analysis group list")
...@@ -261,7 +261,7 @@ def parseQuery(s): ...@@ -261,7 +261,7 @@ def parseQuery(s):
Q(group__name__in=toks.asList()))) Q(group__name__in=toks.asList())))
# Pipeline # Pipeline
pipelineNames = [pipeline.name for pipeline in Pipeline.objects.all()] pipelineNames = list(Pipeline.objects.values_list('name', flat=True))
pipeline = Or(map(CaselessLiteral, pipelineNames)).setName("pipeline name") pipeline = Or(map(CaselessLiteral, pipelineNames)).setName("pipeline name")
pipelineList = OneOrMore(pipeline).setName("pipeline list") pipelineList = OneOrMore(pipeline).setName("pipeline list")
pipelineQ = (Optional(Suppress(Keyword("pipeline:"))) + pipelineList) pipelineQ = (Optional(Suppress(Keyword("pipeline:"))) + pipelineList)
...@@ -269,7 +269,7 @@ def parseQuery(s): ...@@ -269,7 +269,7 @@ def parseQuery(s):
Q(pipeline__name__in=toks.asList()))) Q(pipeline__name__in=toks.asList())))
# Search # Search
searchNames = [search.name for search in Search.objects.all()] searchNames = list(Search.objects.values_list('name', flat=True))
search = Or(map(CaselessLiteral, searchNames)).setName("search name") search = Or(map(CaselessLiteral, searchNames)).setName("search name")
# XXX Branson: The change below was made 2/17/15 to fix a bug in which # XXX Branson: The change below was made 2/17/15 to fix a bug in which
# searches like 'grbevent.ra > 0' failed due to the 'grb' being peeled off # searches like 'grbevent.ra > 0' failed due to the 'grb' being peeled off
......
...@@ -18,7 +18,7 @@ def getLabelQ(): ...@@ -18,7 +18,7 @@ def getLabelQ():
# Note the parse action for labelQ: Replace all tokens with the empty # Note the parse action for labelQ: Replace all tokens with the empty
# string. This basically has the effect of removing any label query terms # string. This basically has the effect of removing any label query terms
# from the query string. # from the query string.
labelNames = [l.name for l in Label.objects.all()] labelNames = list(Label.objects.values_list('name', flat=True))
#label = Or([CaselessLiteral(n) for n in labelNames]).\ #label = Or([CaselessLiteral(n) for n in labelNames]).\
label = Or([CaselessKeyword(n) for n in labelNames]).\ label = Or([CaselessKeyword(n) for n in labelNames]).\
setParseAction( lambda toks: Q(labels__name=toks[0]) ) setParseAction( lambda toks: Q(labels__name=toks[0]) )
...@@ -39,7 +39,7 @@ def getLabelQ(): ...@@ -39,7 +39,7 @@ def getLabelQ():
# as a list of Q objects and separators. # as a list of Q objects and separators.
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def labelQuery(s, names=False): def labelQuery(s, names=False):
labelNames = [l.name for l in Label.objects.all()] labelNames = list(Label.objects.values_list('name', flat=True))
#label = Or([CaselessLiteral(n) for n in labelNames]) #label = Or([CaselessLiteral(n) for n in labelNames])
label = Or([CaselessKeyword(n) for n in labelNames]) label = Or([CaselessKeyword(n) for n in labelNames])
# If the filter objects are going to be applied to Lable # If the filter objects are going to be applied to Lable
...@@ -66,7 +66,7 @@ def labelQuery(s, names=False): ...@@ -66,7 +66,7 @@ def labelQuery(s, names=False):
# The following version is used only for validation. Just to check that # The following version is used only for validation. Just to check that
# the query strictly conforms to the requirements of a label query. # the query strictly conforms to the requirements of a label query.
def parseLabelQuery(s): def parseLabelQuery(s):
labelNames = [l.name for l in Label.objects.all()] labelNames = list(Label.objects.values_list('name', flat=True))
#label = Or([CaselessLiteral(n) for n in labelNames]) #label = Or([CaselessLiteral(n) for n in labelNames])
label = Or([CaselessKeyword(n) for n in labelNames]) label = Or([CaselessKeyword(n) for n in labelNames])
andop = oneOf(", &") andop = oneOf(", &")
......
...@@ -3,11 +3,11 @@ import datetime ...@@ -3,11 +3,11 @@ import datetime
import logging import logging
import pytz import pytz
from django.conf import settings
from django.db.models import Q from django.db.models import Q
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from core.utils import letters_to_int, int_to_letters from core.utils import letters_to_int, int_to_letters
from events.models import Group, Pipeline, Search, Label
# (weak) natural language time parsing. # (weak) natural language time parsing.
from events.nltime import nlTimeExpression as nltime_ from events.nltime import nlTimeExpression as nltime_
from superevents.models import Superevent from superevents.models import Superevent
...@@ -19,7 +19,7 @@ from pyparsing import Word, nums, Literal, CaselessLiteral, delimitedList, \ ...@@ -19,7 +19,7 @@ from pyparsing import Word, nums, Literal, CaselessLiteral, delimitedList, \
Suppress, QuotedString, Keyword, Combine, Or, Optional, OneOrMore, \ Suppress, QuotedString, Keyword, Combine, Or, Optional, OneOrMore, \
ZeroOrMore, alphas, alphanums, Regex, opAssoc, operatorPrecedence, \ ZeroOrMore, alphas, alphanums, Regex, opAssoc, operatorPrecedence, \
oneOf, stringStart, stringEnd, FollowedBy, ParseResults, ParseException, \ oneOf, stringStart, stringEnd, FollowedBy, ParseResults, ParseException, \
CaselessKeyword, pyparsing_common CaselessKeyword, pyparsing_common, tokenMap
# Set up logger # Set up logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -37,9 +37,23 @@ def parse_superevent_id(name, toks, filter_prefix=None): ...@@ -37,9 +37,23 @@ def parse_superevent_id(name, toks, filter_prefix=None):
if (toks.prefix == Superevent.GW_ID_PREFIX): if (toks.prefix == Superevent.GW_ID_PREFIX):
toks.suffix = toks.suffix.upper() toks.suffix = toks.suffix.upper()
# Combine into full ID, get lookup kwargs and convert to a Q object # Combine into full ID and get lookup kwargs
s_id = toks.preprefix + toks.prefix + toks.date + toks.suffix s_id = toks.preprefix + toks.prefix + toks.date + toks.suffix
f_kwargs = Superevent.get_filter_kwargs_for_date_id_lookup(s_id) f_kwargs = Superevent.get_filter_kwargs_for_date_id_lookup(s_id)
# Add any necessary prefix. For example, if we want to look up events
# that are part of a given superevent, we have to add the 'superevent__'
# prefix to the filter kwargs.
if filter_prefix:
# Add '__' to end of filter_prefix
if not filter_prefix.endswith('__'):
filter_prefix += '__'
f_kwargs = {'{pref}{k}'.format(pref=filter_prefix, k=k): v for
k,v in f_kwargs.items()}
# Convert to a Q object
fullQ = Q(**f_kwargs) fullQ = Q(**f_kwargs)
return (name, fullQ) return (name, fullQ)
...@@ -80,7 +94,7 @@ parameter_dicts = { ...@@ -80,7 +94,7 @@ parameter_dicts = {
't_0': { 't_0': {
'keyword': ['t_0', 'gpstime'], 'keyword': ['t_0', 'gpstime'],
'keywordOptional': True, 'keywordOptional': True,
'value': pyparsing_common.number, 'value': pyparsing_common.number.copy(),
'doRange': True, 'doRange': True,
'parseAction': maybeRange('t_0'), 'parseAction': maybeRange('t_0'),
}, },
...@@ -88,7 +102,7 @@ parameter_dicts = { ...@@ -88,7 +102,7 @@ parameter_dicts = {
't_start': { 't_start': {
'keyword': 't_start', 'keyword': 't_start',
'keywordOptional': False, 'keywordOptional': False,
'value': pyparsing_common.number, 'value': pyparsing_common.number.copy(),
'doRange': True, 'doRange': True,
'parseAction': maybeRange('t_start'), 'parseAction': maybeRange('t_start'),
}, },
...@@ -96,7 +110,7 @@ parameter_dicts = { ...@@ -96,7 +110,7 @@ parameter_dicts = {
't_end': { 't_end': {
'keyword': 't_end', 'keyword': 't_end',
'keywordOptional': False, 'keywordOptional': False,
'value': pyparsing_common.number, 'value': pyparsing_common.number.copy(),
'doRange': True, 'doRange': True,
'parseAction': maybeRange('t_end'), 'parseAction': maybeRange('t_end'),
}, },
...@@ -113,16 +127,18 @@ parameter_dicts = { ...@@ -113,16 +127,18 @@ parameter_dicts = {
'preferred_event': { 'preferred_event': {
'keyword': 'preferred_event', 'keyword': 'preferred_event',
'keywordOptional': False, 'keywordOptional': False,
'value': Suppress(Word("GHMTghmt", exact=1)) + Word(nums), 'value': Suppress(Word("GHMTghmt", exact=1)) + \
Word(nums).setParseAction(tokenMap(int)),
'doRange': True, 'doRange': True,
'parseAction': maybeRange("preferred_event", 'parseAction': maybeRange("preferred_event",
dbname="preferred_event__id"), dbname="preferred_event__id"),
}, },
# event: G1234, event: G1234 .. G2234 # event: G1234, event: G1234 .. G2234
'event': { 'event': {
'keyword': 'event', 'keyword': ['event', 'events'],
'keywordOptional': False, 'keywordOptional': False,
'value': Suppress(Word("EGHMTeghmt", exact=1)) + Word(nums), 'value': Suppress(Word("EGHMTeghmt", exact=1)) + \
Word(nums).setParseAction(tokenMap(int)),
'doRange': True, 'doRange': True,
'parseAction': maybeRange("event", dbname="events__id"), 'parseAction': maybeRange("event", dbname="events__id"),
}, },
...@@ -167,7 +183,8 @@ parameter_dicts = { ...@@ -167,7 +183,8 @@ parameter_dicts = {
Optional(Word(nums, exact=2) + Suppress(':') + \ Optional(Word(nums, exact=2) + Suppress(':') + \
Word(nums, exact=2) + Optional(Suppress(':') + \ Word(nums, exact=2) + Optional(Suppress(':') + \
Word(nums, exact=2)))).setParseAction(lambda toks: Word(nums, exact=2)))).setParseAction(lambda toks:
pytz.utc.localize(datetime.datetime(*map(int, toks)))), pytz.timezone(settings.TIME_ZONE).localize(
datetime.datetime(*map(int, toks)))),
'parseAction': maybeRange("created"), 'parseAction': maybeRange("created"),
}, },
# test OR category: test # test OR category: test
...@@ -185,7 +202,7 @@ parameter_dicts = { ...@@ -185,7 +202,7 @@ parameter_dicts = {
'far': { 'far': {
'doRange': False, 'doRange': False,
'value': Suppress(CaselessLiteral('far')) + ExpressionOperator + \ 'value': Suppress(CaselessLiteral('far')) + ExpressionOperator + \
pyparsing_common.number, pyparsing_common.number.copy(),
'parseAction': lambda toks: ("far", 'parseAction': lambda toks: ("far",
Q(**{'preferred_event__far' + toks[0]: toks[1]})), Q(**{'preferred_event__far' + toks[0]: toks[1]})),
}, },
...@@ -194,9 +211,9 @@ parameter_dicts = { ...@@ -194,9 +211,9 @@ parameter_dicts = {
'doRange': False, 'doRange': False,
'value': Suppress(CaselessLiteral('far')) + \ 'value': Suppress(CaselessLiteral('far')) + \
Suppress(Or([CaselessLiteral(d) for d in ['in', ':']])) + \ Suppress(Or([CaselessLiteral(d) for d in ['in', ':']])) + \
pyparsing_common.number + \ pyparsing_common.number.copy() + \
Suppress(Or([CaselessLiteral(op) for op in [',', '..', '-']])) + \ Suppress(Or([CaselessLiteral(op) for op in [',', '..', '-']])) + \
pyparsing_common.number, pyparsing_common.number.copy(),
'parseAction': lambda toks: ("far_range", 'parseAction': lambda toks: ("far_range",
Q(**{'preferred_event__far__range': toks.asList()})), Q(**{'preferred_event__far__range': toks.asList()})),
}, },
...@@ -272,4 +289,3 @@ def parseSupereventQuery(s): ...@@ -272,4 +289,3 @@ def parseSupereventQuery(s):
matches.append(('category', default_Q)) matches.append(('category', default_Q))
return reduce(Q.__and__, [m[1] for m in matches], Q()) return reduce(Q.__and__, [m[1] for m in matches], Q())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment