Индексация множества вложенных моделей с помощью django_elasticsearch_dsl
Я пытаюсь использовать Elasticsearch в своем приложении Django. У меня есть модели Lemma, которые могут иметь несколько форм с одной формой цитирования, которая, в свою очередь, может иметь несколько вариантов написания. Я пытаюсь выполнить поиск по (1) форме цитирования леммы, (2) форме цитирования любой формы Леммы или (3) написанию латинских символов в любой форме Леммы.
Структура в моем models.py:
class Lemma(models.Model):
cf = models.CharField(max_length=200)
pos = models.ForeignKey(Pos, blank=True, null=True, on_delete=models.SET_NULL)
notes = models.TextField(blank=True)
sortform = models.CharField(max_length=200)
class LemmaDef(models.Model):
lemma = models.ForeignKey(Lemma, on_delete=models.CASCADE, related_name="definitions")
definition = models.TextField()
class Form(models.Model):
lemma = models.ForeignKey(Lemma, on_delete=models.CASCADE, related_name="forms")
cf = models.CharField(max_length=200, blank=True)
formtype = models.ManyToManyField(FormType, blank=True)
class Spelling(models.Model):
form = models.ForeignKey(Form, on_delete=models.CASCADE, related_name="spellings")
spelling_lat = models.CharField(max_length=200)
spelling_cun = models.CharField(max_length=200, blank=True)
note = models.CharField(max_length=200, blank=True)
В documents.py у меня есть:
from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
from .models import Lemma, Pos, LemmaDef, Form, Spelling
@registry.register_document
class LemmaDocument(Document):
pos = fields.ObjectField(properties={
"term": fields.TextField()
})
definitions = fields.ObjectField(properties={
"definition": fields.TextField()
})
forms = fields.ObjectField(properties={
"cf": fields.TextField(),
"spellings": fields.ObjectField(properties={
"spelling_lat": fields.TextField()
})
})
class Index:
name = "lemma"
settings = {
"number_of_shards": 1,
"number_of_replicas": 0
}
class Django:
model = Lemma
fields = [
"id",
"cf",
"sortform",
"notes",
]
related_models = [Pos, LemmaDef, Form, Spelling]
def get_instances_from_related(self, related_instance):
if isinstance(related_instance, Pos):
related_instance.lemma_set.all()
elif isinstance(related_instance, LemmaDef):
related_instance.lemma
elif isinstance(related_instance, Form):
related_instance.lemma
elif isinstance(related_instance, Spelling):
related_instance.form.lemma
Когда я запускаю свой поиск, поиск по definitions.definition возвращает ожидаемые результаты, но поиск по полям в forms.cf или forms.spellings.spelling_lat ничего не возвращает.
Выполняется просмотр:
class LemmaSearchView(LemmaListView):
template_name = "emedict/lemma_search.html"
def get(self, request, *args, **kwargs):
form = LemmaAdvancedSearchForm(self.request.GET or None)
if form.is_valid():
term = request.GET["search_term"]
match request.GET["search_type"]:
case "lemma":
fields = [
"cf", "forms.cf", "forms.spellings.spelling_lat", "sortform"
]
case "definition":
fields = ["definitions.definition"]
case _:
fields = [
"cf", "forms.cf", "forms.spellings.spelling_lat", "sortform"
]
# TODO: convert sub nums to regular?
q = edsl.Q(
"multi_match",
query = term,
fields = fields,
fuzziness = "auto"
)
search = LemmaDocument.search().query(q)
qs: QuerySet = search.to_queryset()
self.lemmalist = qs.distinct().order_by("sortform")
return self.render_to_response(self.get_context_data(form=form))
Есть ли что-то, чего я не понимаю в поиске, который выполняется на двух вложенных уровнях?