mirror of
				https://github.com/Alexander-D-Karpov/akarpov
				synced 2025-10-31 11:17:24 +03:00 
			
		
		
		
	updated search
This commit is contained in:
		
							parent
							
								
									600c903a68
								
							
						
					
					
						commit
						f4ca7db696
					
				|  | @ -88,8 +88,12 @@ def get_liked(self, obj): | ||||||
| 
 | 
 | ||||||
|     @extend_schema_field(ListAlbumSerializer) |     @extend_schema_field(ListAlbumSerializer) | ||||||
|     def get_album(self, obj): |     def get_album(self, obj): | ||||||
|         if obj.album: |         if obj.album_id: | ||||||
|             return ListAlbumSerializer(Album.objects.cache().get(id=obj.album_id)).data |             try: | ||||||
|  |                 album = Album.objects.cache().get(id=obj.album_id) | ||||||
|  |                 return ListAlbumSerializer(album).data | ||||||
|  |             except Album.DoesNotExist: | ||||||
|  |                 return None | ||||||
|         return None |         return None | ||||||
| 
 | 
 | ||||||
|     @extend_schema_field(ListAuthorSerializer(many=True)) |     @extend_schema_field(ListAuthorSerializer(many=True)) | ||||||
|  | @ -105,15 +109,16 @@ def get_image(self, obj): | ||||||
|         img = None |         img = None | ||||||
|         if obj.image_cropped: |         if obj.image_cropped: | ||||||
|             img = obj.image_cropped |             img = obj.image_cropped | ||||||
|         else: |         elif obj.album_id: | ||||||
|  |             try: | ||||||
|                 album = Album.objects.cache().get(id=obj.album_id) |                 album = Album.objects.cache().get(id=obj.album_id) | ||||||
|                 if album.image_cropped: |                 if album.image_cropped: | ||||||
|                     img = album.image_cropped |                     img = album.image_cropped | ||||||
|             else: |             except Album.DoesNotExist: | ||||||
|                 authors = Author.objects.cache().filter( |                 pass | ||||||
|                     Q(songs__id=obj.id) & ~Q(image="") |         if not img: | ||||||
|                 ) |             authors = Author.objects.cache().filter(Q(songs__id=obj.id) & ~Q(image="")) | ||||||
|                 if authors: |             if authors.exists(): | ||||||
|                 img = authors.first().image_cropped |                 img = authors.first().image_cropped | ||||||
|         if img: |         if img: | ||||||
|             return self.context["request"].build_absolute_uri(img.url) |             return self.context["request"].build_absolute_uri(img.url) | ||||||
|  |  | ||||||
|  | @ -48,7 +48,7 @@ class SongDocument(Document): | ||||||
|         attr="name", |         attr="name", | ||||||
|         fields={ |         fields={ | ||||||
|             "raw": fields.KeywordField(), |             "raw": fields.KeywordField(), | ||||||
|             "exact": fields.KeywordField(normalizer="lowercase"), |             "exact": fields.KeywordField(normalizer="lowercase_normalizer"), | ||||||
|         }, |         }, | ||||||
|     ) |     ) | ||||||
|     name_transliterated = fields.TextField( |     name_transliterated = fields.TextField( | ||||||
|  | @ -67,6 +67,13 @@ class Index: | ||||||
|         settings = { |         settings = { | ||||||
|             "number_of_shards": 1, |             "number_of_shards": 1, | ||||||
|             "number_of_replicas": 0, |             "number_of_replicas": 0, | ||||||
|  |             "normalizer": { | ||||||
|  |                 "lowercase_normalizer": { | ||||||
|  |                     "type": "custom", | ||||||
|  |                     "char_filter": [], | ||||||
|  |                     "filter": ["lowercase"], | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|             "analysis": { |             "analysis": { | ||||||
|                 "filter": { |                 "filter": { | ||||||
|                     "my_transliterator": { |                     "my_transliterator": { | ||||||
|  |  | ||||||
|  | @ -8,97 +8,30 @@ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def search_song(query): | def search_song(query): | ||||||
|     # Split query into potential track and artist parts |  | ||||||
|     parts = [part.strip() for part in query.split("-")] |  | ||||||
|     track_query = parts[0] |  | ||||||
|     artist_query = parts[1] if len(parts) > 1 else None |  | ||||||
| 
 |  | ||||||
|     search = SongDocument.search() |     search = SongDocument.search() | ||||||
| 
 | 
 | ||||||
|     # Base queries for track name with high boost |     # Build a multi_match query that searches in song name, authors' names, and album names | ||||||
|     should_queries = [ |     multi_match_query = ES_Q( | ||||||
|         ES_Q("match_phrase", name={"query": track_query, "boost": 10}), |         "multi_match", | ||||||
|         ES_Q("match", name={"query": track_query, "fuzziness": "AUTO", "boost": 8}), |         query=query, | ||||||
|         ES_Q("wildcard", name={"value": f"*{track_query.lower()}*", "boost": 6}), |         fields=[ | ||||||
|         ES_Q( |             "name^5", | ||||||
|             "match", |             "name.raw^10", | ||||||
|             name_transliterated={"query": track_query, "fuzziness": "AUTO", "boost": 5}, |             "name.exact^15", | ||||||
|         ), |             "authors.name^4", | ||||||
|     ] |             "authors.name.raw^8", | ||||||
| 
 |             "authors.name.exact^12", | ||||||
|     # Add artist-specific queries if artist part exists |             "album.name^3", | ||||||
|     if artist_query: |             "album.name.raw^6", | ||||||
|         should_queries.extend( |             "album.name.exact^9", | ||||||
|             [ |         ], | ||||||
|                 ES_Q( |         fuzziness="AUTO", | ||||||
|                     "nested", |         operator="and", | ||||||
|                     path="authors", |         type="best_fields", | ||||||
|                     query=ES_Q( |  | ||||||
|                         "match_phrase", name={"query": artist_query, "boost": 4} |  | ||||||
|                     ), |  | ||||||
|                 ), |  | ||||||
|                 ES_Q( |  | ||||||
|                     "nested", |  | ||||||
|                     path="authors", |  | ||||||
|                     query=ES_Q( |  | ||||||
|                         "match", |  | ||||||
|                         name={"query": artist_query, "fuzziness": "AUTO", "boost": 3}, |  | ||||||
|                     ), |  | ||||||
|                 ), |  | ||||||
|                 ES_Q( |  | ||||||
|                     "nested", |  | ||||||
|                     path="authors", |  | ||||||
|                     query=ES_Q( |  | ||||||
|                         "wildcard", |  | ||||||
|                         name={"value": f"*{artist_query.lower()}*", "boost": 2}, |  | ||||||
|                     ), |  | ||||||
|                 ), |  | ||||||
|             ] |  | ||||||
|     ) |     ) | ||||||
|     else: |  | ||||||
|         # If no explicit artist, still search in authors but with lower boost |  | ||||||
|         should_queries.extend( |  | ||||||
|             [ |  | ||||||
|                 ES_Q( |  | ||||||
|                     "nested", |  | ||||||
|                     path="authors", |  | ||||||
|                     query=ES_Q("match_phrase", name={"query": track_query, "boost": 2}), |  | ||||||
|                 ), |  | ||||||
|                 ES_Q( |  | ||||||
|                     "nested", |  | ||||||
|                     path="authors", |  | ||||||
|                     query=ES_Q( |  | ||||||
|                         "match", |  | ||||||
|                         name={"query": track_query, "fuzziness": "AUTO", "boost": 1}, |  | ||||||
|                     ), |  | ||||||
|                 ), |  | ||||||
|             ] |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|     # Add album queries with lower boost |  | ||||||
|     should_queries.extend( |  | ||||||
|         [ |  | ||||||
|             ES_Q( |  | ||||||
|                 "nested", |  | ||||||
|                 path="album", |  | ||||||
|                 query=ES_Q("match_phrase", name={"query": track_query, "boost": 1.5}), |  | ||||||
|             ), |  | ||||||
|             ES_Q( |  | ||||||
|                 "nested", |  | ||||||
|                 path="album", |  | ||||||
|                 query=ES_Q( |  | ||||||
|                     "match", |  | ||||||
|                     name={"query": track_query, "fuzziness": "AUTO", "boost": 1}, |  | ||||||
|                 ), |  | ||||||
|             ), |  | ||||||
|         ] |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
|     # Combine all queries with minimum_should_match=1 |  | ||||||
|     search_query = ES_Q("bool", should=should_queries, minimum_should_match=1) |  | ||||||
| 
 | 
 | ||||||
|     # Execute search with size limit |     # Execute search with size limit | ||||||
|     search = search.query(search_query).extra(size=20) |     search = search.query(multi_match_query).extra(size=20) | ||||||
|     response = search.execute() |     response = search.execute() | ||||||
| 
 | 
 | ||||||
|     if response.hits: |     if response.hits: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user