@@ -167,39 +167,94 @@ def lookup(
167167 use_shared ,
168168 threshold : int = 75 ,
169169 ):
170+ exact_results = self .lookup_scopes (
171+ source_language = source_language ,
172+ target_language = target_language ,
173+ text = text ,
174+ user = user ,
175+ project = project ,
176+ use_shared = use_shared ,
177+ exact = True ,
178+ )
179+ if exact_results :
180+ return exact_results
181+
170182 # Adjust similarity based on string length to get more relevant matches
171183 # for long strings
172184 similarity_threshold = self .threshold_to_similarity (text , threshold )
173185
174- results = self . none ()
186+ results : list [ Memory ] = []
175187
176188 while len (results ) == 0 and similarity_threshold > MIN_SIMILARITY_THRESHOLD :
177189 # Change PostgreSQL similarity threshold configuration
178190 adjust_similarity_threshold (similarity_threshold )
179191
180192 # Actual database query
181- results = (
182- self .prefetch_project ()
183- .filter_type (
184- # Type filtering
185- user = user ,
186- project = project ,
187- use_shared = use_shared ,
188- from_file = True ,
189- )
190- .filter (
191- # Full-text search on source
192- source__search = text ,
193- # Language filtering
194- source_language = source_language ,
195- target_language = target_language ,
196- )[:50 ]
193+ results = self .lookup_scopes (
194+ source_language = source_language ,
195+ target_language = target_language ,
196+ text = text ,
197+ user = user ,
198+ project = project ,
199+ use_shared = use_shared ,
197200 )
198201 # Decrease threshold in case no matches were found
199202 similarity_threshold -= 0.05
200203
201204 return results
202205
206+ def lookup_scopes (
207+ self ,
208+ * ,
209+ source_language ,
210+ target_language ,
211+ text : str ,
212+ user ,
213+ project ,
214+ use_shared : bool ,
215+ exact : bool = False ,
216+ limit : int = 50 ,
217+ ) -> list [Memory ]:
218+ base = self .prefetch_project ()
219+ common_filters = {
220+ "source_language" : source_language ,
221+ "target_language" : target_language ,
222+ }
223+ if exact :
224+ common_filters ["source" ] = text
225+ else :
226+ common_filters ["source__search" ] = text
227+
228+ results : list [Memory ] = []
229+ seen : set [int ] = set ()
230+
231+ for query in self .iter_lookup_scope_queries (
232+ user = user ,
233+ project = project ,
234+ use_shared = use_shared ,
235+ ):
236+ for memory in base .filter (query , ** common_filters )[:limit ]:
237+ if memory .pk in seen :
238+ continue
239+ seen .add (memory .pk )
240+ results .append (memory )
241+ if len (results ) >= limit :
242+ return results
243+
244+ return results
245+
246+ def iter_lookup_scope_queries (
247+ self , * , user , project , use_shared : bool
248+ ) -> tuple [Q , ...]:
249+ queries : list [Q ] = [Q (from_file = True )]
250+ if project is not None :
251+ queries .append (Q (project = project , shared = False ))
252+ if use_shared :
253+ queries .append (Q (shared = True ))
254+ if user is not None :
255+ queries .append (Q (user = user , shared = False ))
256+ return tuple (queries )
257+
203258 def prefetch_lang (self ):
204259 return self .prefetch_related ("source_language" , "target_language" )
205260
@@ -601,6 +656,32 @@ class Meta:
601656 condition = Q (from_file = True ),
602657 name = "memory_from_file" ,
603658 ),
659+ models .Index (
660+ "source_language" ,
661+ "target_language" ,
662+ condition = Q (from_file = True ),
663+ name = "memory_file_lang_idx" ,
664+ ),
665+ models .Index (
666+ "project" ,
667+ "source_language" ,
668+ "target_language" ,
669+ condition = Q (project__isnull = False , shared = False ),
670+ name = "memory_project_lang_idx" ,
671+ ),
672+ models .Index (
673+ "user" ,
674+ "source_language" ,
675+ "target_language" ,
676+ condition = Q (user__isnull = False , shared = False ),
677+ name = "memory_user_lang_idx" ,
678+ ),
679+ models .Index (
680+ "source_language" ,
681+ "target_language" ,
682+ condition = Q (shared = True ),
683+ name = "memory_shared_lang_idx" ,
684+ ),
604685 ]
605686
606687 def __str__ (self ) -> str :
0 commit comments