mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2025-02-22 13:00:34 +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,16 +109,17 @@ 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:
|
||||||
album = Album.objects.cache().get(id=obj.album_id)
|
try:
|
||||||
if album.image_cropped:
|
album = Album.objects.cache().get(id=obj.album_id)
|
||||||
img = album.image_cropped
|
if album.image_cropped:
|
||||||
else:
|
img = album.image_cropped
|
||||||
authors = Author.objects.cache().filter(
|
except Album.DoesNotExist:
|
||||||
Q(songs__id=obj.id) & ~Q(image="")
|
pass
|
||||||
)
|
if not img:
|
||||||
if authors:
|
authors = Author.objects.cache().filter(Q(songs__id=obj.id) & ~Q(image=""))
|
||||||
img = authors.first().image_cropped
|
if authors.exists():
|
||||||
|
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)
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -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