51
51
# Use python port of Porter2 stemmer.
52
52
from search .pyporter2 import Stemmer
53
53
54
+ class Error (Exception ):
55
+ """Base search module error type."""
56
+
57
+ class IndexTitleError (Error ):
58
+ """Raised when INDEX_TITLE_FROM_PROP or title alterations are incorrect."""
59
+
54
60
# Following module-level constants are cached in instance
55
61
56
62
KEY_NAME_DELIMITER = '||' # Used to hold arbitrary strings in key names.
@@ -125,6 +131,14 @@ def get_title(key_name=''):
125
131
else :
126
132
return frags [2 ]
127
133
134
+ @staticmethod
135
+ def get_index_num (key_name = '' ):
136
+ frags = key_name .split (KEY_NAME_DELIMITER )
137
+ if len (frags ) < 2 :
138
+ return '1'
139
+ else :
140
+ return frags [1 ]
141
+
128
142
@classmethod
129
143
def put_index (cls , parent , phrases , index_num = 1 ):
130
144
parent_key = parent .key ()
@@ -136,11 +150,9 @@ def put_index(cls, parent, phrases, index_num=1):
136
150
137
151
class LiteralIndex (SearchIndex ):
138
152
"""Index model for non-inflected search phrases."""
139
- pass
140
153
141
154
class StemmedIndex (SearchIndex ):
142
155
"""Index model for stemmed (inflected) search phrases."""
143
- pass
144
156
145
157
146
158
class Searchable (object ):
@@ -409,6 +421,23 @@ def search(cls, phrase, limit=10, keys_only=False):
409
421
else :
410
422
return [cls .get (key_and_title [0 ]) for key_and_title in key_list ]
411
423
424
+ def indexed_title_changed (self ):
425
+ """Renames index entities for this model to match new title."""
426
+ klass = StemmedIndex if self .INDEX_STEMMING else LiteralIndex
427
+ query = klass .all (keys_only = True ).ancestor (self .key ())
428
+ old_index_keys = query .fetch (1000 )
429
+ if not hasattr (self , 'INDEX_TITLE_FROM_PROP' ):
430
+ raise IndexTitleError ('Must declare a property name via INDEX_TITLE_FROM_PROP' )
431
+ new_keys = []
432
+ for old_key in old_index_keys :
433
+ old_index = db .get (old_key )
434
+ index_num = SearchIndex .get_index_num (old_key .name ())
435
+ index_key = klass .put_index (parent = self , index_num = index_num ,
436
+ phrases = old_index .phrases )
437
+ new_keys .append (index_key )
438
+ delete_keys = filter (lambda key : key not in new_keys , old_index_keys )
439
+ db .delete (delete_keys )
440
+
412
441
def get_search_phrases (self , indexing_func = None ):
413
442
"""Returns search phrases from properties in a given Model instance.
414
443
0 commit comments