Doanh Van Vu commited on
Commit
7083cd1
·
1 Parent(s): 2dfb75f

Refactor RecommendationService to remove filtering logic

Browse files

- Removed the filter construction and fallback mechanism from the recommendation process, simplifying the query to Pinecone by applying no filters.
- Updated logging to reflect the changes, ensuring clarity in the absence of filters during mentor queries.
- Enhanced the overall readability and maintainability of the code by eliminating unnecessary complexity in the filtering logic.

Files changed (1) hide show
  1. services/recommendation_service.py +3 -77
services/recommendation_service.py CHANGED
@@ -90,56 +90,18 @@ class RecommendationService:
90
  embedding_time = time.perf_counter() - embedding_start
91
  logger.info(f"[RECOMMEND] Query embedding generated in {embedding_time:.3f}s")
92
 
93
- filter_start = time.perf_counter()
94
- filter_dict = self._build_filter(mentee_data)
95
- filter_time = time.perf_counter() - filter_start
96
- logger.info(f"[RECOMMEND] Filter built in {filter_time:.3f}s: {filter_dict}")
97
-
98
  pinecone_start = time.perf_counter()
99
  similar_mentors = self.pinecone_service.query_similar(
100
  query_vector=query_embedding,
101
  top_k=top_k,
102
- filter=filter_dict if filter_dict else None,
103
  include_metadata=True
104
  )
105
  pinecone_time = time.perf_counter() - pinecone_start
106
- logger.info(f"[RECOMMEND] Pinecone query completed in {pinecone_time:.3f}s: found {len(similar_mentors)} candidates")
107
-
108
- if not similar_mentors and filter_dict:
109
- has_strict_filters = "rating" in filter_dict or "has_availability" in filter_dict
110
-
111
- if has_strict_filters:
112
- logger.warning(f"[RECOMMEND] No results with strict filter (rating/availability), trying fallback with relaxed filter")
113
- logger.info(f"[RECOMMEND] Original filter: {filter_dict}")
114
-
115
- fallback_filter = {}
116
- if mentee_data.get("skill_ids"):
117
- fallback_filter["skill_ids"] = {"$in": [str(int(id)) for id in mentee_data["skill_ids"]]}
118
- if mentee_data.get("domain_ids"):
119
- fallback_filter["domain_ids"] = {"$in": [str(int(id)) for id in mentee_data["domain_ids"]]}
120
- if mentee_data.get("career_id"):
121
- fallback_filter["career_id"] = int(mentee_data["career_id"])
122
- if mentee_data.get("status"):
123
- fallback_filter["status"] = str(mentee_data["status"])
124
- else:
125
- fallback_filter["status"] = "ACTIVATED"
126
-
127
- logger.info(f"[RECOMMEND] Fallback filter (removed rating/availability constraints): {fallback_filter}")
128
-
129
- fallback_start = time.perf_counter()
130
- similar_mentors = self.pinecone_service.query_similar(
131
- query_vector=query_embedding,
132
- top_k=top_k,
133
- filter=fallback_filter if fallback_filter else None,
134
- include_metadata=True
135
- )
136
- fallback_time = time.perf_counter() - fallback_start
137
- logger.info(f"[RECOMMEND] Fallback query completed in {fallback_time:.3f}s: found {len(similar_mentors)} candidates")
138
- else:
139
- logger.warning(f"[RECOMMEND] No results found even without strict filters")
140
 
141
  if not similar_mentors:
142
- logger.warning("[RECOMMEND] No similar mentors found after fallback, returning empty list")
143
  return []
144
 
145
  metadata_start = time.perf_counter()
@@ -191,42 +153,6 @@ class RecommendationService:
191
  logger.error(f"[RECOMMEND] Failed to recommend mentors after {total_time:.3f}s: {str(e)}", exc_info=True)
192
  raise
193
 
194
- def _build_filter(self, mentee_data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
195
- filter_dict = {}
196
-
197
- if mentee_data.get("min_rating"):
198
- min_rating = float(mentee_data["min_rating"])
199
- filter_dict["rating"] = {"$gte": min_rating}
200
- logger.info(f"[RECOMMEND] Adding rating filter: >= {min_rating}")
201
-
202
- if mentee_data.get("require_availability"):
203
- filter_dict["has_availability"] = True
204
- logger.info(f"[RECOMMEND] Adding availability filter: has_availability=True")
205
-
206
- if mentee_data.get("skill_ids"):
207
- skill_ids = [str(int(id)) for id in mentee_data["skill_ids"]]
208
- filter_dict["skill_ids"] = {"$in": skill_ids}
209
- logger.info(f"[RECOMMEND] Adding skill_ids filter: {skill_ids}")
210
-
211
- if mentee_data.get("domain_ids"):
212
- domain_ids = [str(int(id)) for id in mentee_data["domain_ids"]]
213
- filter_dict["domain_ids"] = {"$in": domain_ids}
214
- logger.info(f"[RECOMMEND] Adding domain_ids filter: {domain_ids}")
215
-
216
- if mentee_data.get("career_id"):
217
- career_id = int(mentee_data["career_id"])
218
- filter_dict["career_id"] = career_id
219
- logger.info(f"[RECOMMEND] Adding career_id filter: {career_id}")
220
-
221
- if mentee_data.get("status"):
222
- filter_dict["status"] = str(mentee_data["status"])
223
- logger.info(f"[RECOMMEND] Adding status filter: {mentee_data['status']}")
224
- else:
225
- filter_dict["status"] = "ACTIVATED"
226
- logger.info(f"[RECOMMEND] Adding default status filter: ACTIVATED")
227
-
228
- return filter_dict if filter_dict else None
229
-
230
  def delete_mentor(self, mentor_id: str) -> bool:
231
  try:
232
  return self.pinecone_service.delete_mentor(mentor_id)
 
90
  embedding_time = time.perf_counter() - embedding_start
91
  logger.info(f"[RECOMMEND] Query embedding generated in {embedding_time:.3f}s")
92
 
 
 
 
 
 
93
  pinecone_start = time.perf_counter()
94
  similar_mentors = self.pinecone_service.query_similar(
95
  query_vector=query_embedding,
96
  top_k=top_k,
97
+ filter=None,
98
  include_metadata=True
99
  )
100
  pinecone_time = time.perf_counter() - pinecone_start
101
+ logger.info(f"[RECOMMEND] Pinecone query completed in {pinecone_time:.3f}s: found {len(similar_mentors)} candidates (no filter applied)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
  if not similar_mentors:
104
+ logger.warning("[RECOMMEND] No similar mentors found, returning empty list")
105
  return []
106
 
107
  metadata_start = time.perf_counter()
 
153
  logger.error(f"[RECOMMEND] Failed to recommend mentors after {total_time:.3f}s: {str(e)}", exc_info=True)
154
  raise
155
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  def delete_mentor(self, mentor_id: str) -> bool:
157
  try:
158
  return self.pinecone_service.delete_mentor(mentor_id)