Мне нужно реализовать функцию поиска, которая будет отказоустойчивой.
Сейчас у меня следующая ситуация:
Модели:
class Tag(models.Model):
name = models.CharField(max_length=255)
class Illustration(models.Model):
name = models.CharField(max_length=255)
tags = models.ManyToManyField(Tag)
Запрос:
queryset.annotate(similarity=TrigramSimilarity('name', fulltext) + TrigramSimilarity('tags__name', fulltext))
Пример данных:
Иллюстрации:
ID | Name | Tags |
---|--------|-------------------|
1 | "Dog" | "Animal", "Brown" |
2 | "Cat" | "Animals" |
Иллюстрация имеет теги:
ID_Illustration | ID_Tag |
----------------|--------|
1 | 1 |
1 | 2 |
2 | 3 |
Теги:
ID_Tag | Name |
-------|----------|
1 | Animal |
2 | Brown |
3 | Animals |
Когда я запускаю запрос с "Animal"
, сходство для "Dog"
должно быть выше, чем для "Cat"
, так как это идеальное совпадение.
К сожалению, оба тега каким-то образом рассматриваются вместе.
В настоящее время похоже, что он объединяет теги. в одну строку, а затем проверяет сходство:
TrigramSimilarity("Animal Brown", "Animal") => X
Но я хотел бы настроить его таким образом, чтобы получить максимальное сходство между именем экземпляра Illustration
и его тегами:
Max([
TrigramSimilarity('Name', "Animal"),
TrigramSimilarity("Tag_1", "Animal"),
TrigramSimilarity("Tag_2", "Animal"),
]) => X
Edit1: я пытаюсь запросить все иллюстрации, где либо заголовок, либо один из тегов имеют сходство больше, чем X.
Edit2: Дополнительный пример:
полный текст = 'Животное'
TrigramSimilarity('Животное коричневое', полный текст) => x TrigramSimilarity('Животные', полный текст) => y
Где х ‹ у
Но то, что я хочу, на самом деле
TrigramSimilarity(Max(['Животное', 'Коричневый]), полный текст) => x (Сходство с животным) TrigramSimilarity('Животные', полный текст) => y
Где х > у
TrigramSimilarity
функцией Python или она переводится в SQL? Если это python, я не думаю, что вы можете использовать его в вызовеannotate
, как вы пытаетесь сделать. - person Laurent S   schedule 07.02.2018