How to sort TextFields (strings) in Django using ElasticSearch-dsl?
I cannot find the solution for this online so i hope anyone here could help.
I have a ChardField in models.py i want to sort after rebuilding the index in ElasticSearch (version 7). I'm using 'django_elasticsearch_dsl' as my pip.
I read something about adding 'fielddata' as a property in 'documents.py' or changing the TextField() type to KeywordField() but i have no idea how to do this properly.
My documents.py so far:
from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
from .models import Journey
@registry.register_document
class JourneyDocument(Document):
class Index:
name = 'journeys'
settings = {'number_of_shards': 1,
'number_of_replicas': 0}
class Django:
model = Journey # The model associated with this Document
fields = [
'id',
'departure_time',
'return_time',
'departure_station_name',
'return_station_name',
'covered_distance',
'duration',
]
..and my models.py is:
class Journey (models.Model):
id = models.BigAutoField(primary_key=True)
departure_time = models.DateTimeField(auto_now = False, auto_now_add = False, default=timezone.now)
return_time = models.DateTimeField(auto_now=False, auto_now_add=False, default=timezone.now)
departure_station = models.ForeignKey(Station, on_delete=models.CASCADE, related_name='departure_station')
departure_station_name = models.CharField(max_length=50, default="-")
return_station = models.ForeignKey(Station, on_delete=models.CASCADE, related_name='return_station')
return_station_name = models.CharField(max_length=50, default="-")
covered_distance = models.DecimalField(max_digits=12, decimal_places=2, validators=[MinValueValidator(10, "Covered distance of the journey has to be bigger than 10.")])
duration = models.PositiveIntegerField(validators=[MinValueValidator(10, "Duration of the journey has to be bigger than 10s.")])
So how can i sort the query results by 'departure_station_name' in views.py like this:
s.sort("departure_station_name")
Right now im getting:
RequestError(400, 'search_phase_execution_exception', 'Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [departure_station_name] in order to load field data by uninverting the inverted index. Note that this can use significant memory.')
So far I have tried converting my field ('departure_station_name') and ('return_station_name') to KeywordFields like this:
@registry.register_document
class JourneyDocument(Document):
class Index:
name = 'journeys'
departure_station_name = fields.KeywordField(fielddata=True)
return_station_name = fields.KeywordField(fielddata=True)
settings = {'number_of_shards': 1,
'number_of_replicas': 0}
class Django:
model = Journey # The model associated with this Document
fields = [
'id',
'departure_time',
'return_time',
'departure_station_name',
'return_station_name',
'covered_distance',
'duration',
]
..but to be honest i have no idea how to do it as there is limited amount of documentation or examples online.