Make searching on indentifiers work

This commit is contained in:
Charles Haley 2011-03-01 13:37:10 +00:00
parent c82ef56145
commit 3d1b02d10f
2 changed files with 70 additions and 55 deletions

View File

@ -418,9 +418,9 @@ class ResultCache(SearchQueryParser): # {{{
return matches return matches
def get_user_category_matches(self, location, query, candidates): def get_user_category_matches(self, location, query, candidates):
res = set([]) matches = set([])
if self.db_prefs is None or len(query) < 2: if self.db_prefs is None or len(query) < 2:
return res return matches
user_cats = self.db_prefs.get('user_categories', []) user_cats = self.db_prefs.get('user_categories', [])
c = set(candidates) c = set(candidates)
@ -435,10 +435,56 @@ class ResultCache(SearchQueryParser): # {{{
for (item, category, ign) in user_cats[key]: for (item, category, ign) in user_cats[key]:
s = self.get_matches(category, '=' + item, candidates=c) s = self.get_matches(category, '=' + item, candidates=c)
c -= s c -= s
res |= s matches |= s
if query == 'false': if query == 'false':
return candidates - res return candidates - matches
return res return matches
def get_keypair_matches(self, location, query, candidates):
matches = set([])
if query.find(':') >= 0:
q = [q.strip() for q in query.split(':')]
if len(q) != 2:
raise ParseException(query, len(query),
'Invalid query format for colon-separated search', self)
(keyq, valq) = q
keyq_mkind, keyq = self._matchkind(keyq)
valq_mkind, valq = self._matchkind(valq)
else:
keyq = keyq_mkind = ''
valq_mkind, valq = self._matchkind(query)
loc = self.field_metadata[location]['rec_index']
for id_ in candidates:
item = self._data[id_]
if item is None or item[loc] is None:
continue
pairs = [p.strip() for p in item[loc].split(',')]
for pair in pairs:
parts = pair.split(':')
if len(parts) != 2:
continue
k = parts[:1]
v = parts[1:]
if keyq and not _match(keyq, k, keyq_mkind):
continue
if valq and not _match(valq, v, valq_mkind):
continue
matches.add(id_)
return matches
def _matchkind(self, query):
matchkind = CONTAINS_MATCH
if (len(query) > 1):
if query.startswith('\\'):
query = query[1:]
elif query.startswith('='):
matchkind = EQUALS_MATCH
query = query[1:]
elif query.startswith('~'):
matchkind = REGEXP_MATCH
query = query[1:]
return matchkind, query
def get_matches(self, location, query, candidates=None, def get_matches(self, location, query, candidates=None,
allow_recursion=True): allow_recursion=True):
@ -504,22 +550,18 @@ class ResultCache(SearchQueryParser): # {{{
len(item[loc].split(ms)) if item[loc] is not None else 0 len(item[loc].split(ms)) if item[loc] is not None else 0
return self.get_numeric_matches(location, query[1:], return self.get_numeric_matches(location, query[1:],
candidates, val_func=vf) candidates, val_func=vf)
# special case: identifiers. isbn is a special case within the case
if location == 'identifiers':
return self.get_keypair_matches(location, query, candidates)
if location == 'isbn':
return self.get_keypair_matches('identifiers', '=isbn:'+query, candidates)
# check for user categories # check for user categories
if len(location) >= 2 and location.startswith('@'): if len(location) >= 2 and location.startswith('@'):
return self.get_user_category_matches(location[1:], query.lower(), return self.get_user_category_matches(location[1:], query.lower(),
candidates) candidates)
# everything else, or 'all' matches # everything else, or 'all' matches
matchkind = CONTAINS_MATCH matchkind, query = self._matchkind(query)
if (len(query) > 1):
if query.startswith('\\'):
query = query[1:]
elif query.startswith('='):
matchkind = EQUALS_MATCH
query = query[1:]
elif query.startswith('~'):
matchkind = REGEXP_MATCH
query = query[1:]
if matchkind != REGEXP_MATCH: if matchkind != REGEXP_MATCH:
# leave case in regexps because it can be significant e.g. \S \W \D # leave case in regexps because it can be significant e.g. \S \W \D
query = icu_lower(query) query = icu_lower(query)

View File

@ -119,15 +119,6 @@ class FieldMetadata(dict):
'search_terms':['formats', 'format'], 'search_terms':['formats', 'format'],
'is_custom':False, 'is_custom':False,
'is_category':True}), 'is_category':True}),
('identifiers', {'table':None,
'column':None,
'datatype':'text',
'is_multiple':',',
'kind':'field',
'name':_('Identifiers'),
'search_terms':['identifiers', 'identifier'],
'is_custom':False,
'is_category':True}),
('publisher', {'table':'publishers', ('publisher', {'table':'publishers',
'column':'name', 'column':'name',
'link_column':'publisher', 'link_column':'publisher',
@ -171,6 +162,15 @@ class FieldMetadata(dict):
'search_terms':['tags', 'tag'], 'search_terms':['tags', 'tag'],
'is_custom':False, 'is_custom':False,
'is_category':True}), 'is_category':True}),
('identifiers', {'table':None,
'column':None,
'datatype':'text',
'is_multiple':',',
'kind':'field',
'name':_('Identifiers'),
'search_terms':['identifiers', 'identifier', 'isbn'],
'is_custom':False,
'is_category':True}),
('author_sort',{'table':None, ('author_sort',{'table':None,
'column':None, 'column':None,
'datatype':'text', 'datatype':'text',
@ -206,15 +206,6 @@ class FieldMetadata(dict):
'search_terms':['cover'], 'search_terms':['cover'],
'is_custom':False, 'is_custom':False,
'is_category':False}), 'is_category':False}),
('flags', {'table':None,
'column':None,
'datatype':'text',
'is_multiple':None,
'kind':'field',
'name':None,
'search_terms':[],
'is_custom':False,
'is_category':False}),
('id', {'table':None, ('id', {'table':None,
'column':None, 'column':None,
'datatype':'int', 'datatype':'int',
@ -224,22 +215,13 @@ class FieldMetadata(dict):
'search_terms':[], 'search_terms':[],
'is_custom':False, 'is_custom':False,
'is_category':False}), 'is_category':False}),
('isbn', {'table':None, ('last_modified', {'table':None,
'column':None, 'column':None,
'datatype':'text', 'datatype':'datetime',
'is_multiple':None, 'is_multiple':None,
'kind':'field', 'kind':'field',
'name':None, 'name':_('Date'),
'search_terms':['isbn'], 'search_terms':['last_modified'],
'is_custom':False,
'is_category':False}),
('lccn', {'table':None,
'column':None,
'datatype':'text',
'is_multiple':None,
'kind':'field',
'name':None,
'search_terms':[],
'is_custom':False, 'is_custom':False,
'is_category':False}), 'is_category':False}),
('ondevice', {'table':None, ('ondevice', {'table':None,
@ -305,15 +287,6 @@ class FieldMetadata(dict):
'search_terms':['date'], 'search_terms':['date'],
'is_custom':False, 'is_custom':False,
'is_category':False}), 'is_category':False}),
('last_modified', {'table':None,
'column':None,
'datatype':'datetime',
'is_multiple':None,
'kind':'field',
'name':_('Date'),
'search_terms':['last_modified'],
'is_custom':False,
'is_category':False}),
('title', {'table':None, ('title', {'table':None,
'column':None, 'column':None,
'datatype':'text', 'datatype':'text',