0

У меня есть следующая модель:Как сделать сортировку в БД по количеству элементов в ListField?

class Departments(Document): 
    _id = fields.ObjectIdField() 
    name = fields.StringField(blank=True, null=True) 
    department_id = fields.StringField(blank=True, null=True) # Added 
    list_of_users = fields.ListField(blank=True, null=True) 
    list_of_workstations = fields.ListField(blank=True, null=True) 

Как вы можете видеть list_of_users и list_of_workstations являются списки элементов.

Я написал код в Python, который берет все данные из БД, помещает его в dict и затем сортирует по мере необходимости, но работает слишком медленно.

Как можно сортировать Departments прямо в БД по длине list_of_users или list_of_workstations или по отношению list_of_users/list_of_workstations, что-то вроде:

departments = DepartmentStats.objects.order_by(len(list_of_users)).dsc 

или

departments = DepartmentStats.objects.order_by(len(list_of_users)/len(list_of_workstations)).dsc 

?

+0

Читать эту документацию, вероятно, вы найдете то, что вы хотите. https://docs.djangoproject.com/ru/dev/topics/db/aggregation/ –

ответ

0

Если кому-то нужен необработанный запрос:

departments = DepartmentStats._get_collection().aggregate([ 
    {"$project": { 
     "department_id": 1, 
     "name": 1, 
     "list_of_users": 1, 
    }}, 
    {"$sort": {"list_of_users": -1}}, 
]) 

и случай, когда результат должен быть отсортирован по соотношению list_of_users/list_of_workstations

departments = DepartmentStats._get_collection().aggregate([ 
    {"$project": { 
     "department_id": 1, 
     "name": 1, 
     "list_of_users": 1, 
     "len_list_of_items": {"$divide": [{"$size": "$list_of_users"}, 
              {"$size": "$list_of_workstations"}]} 
    }}, 
    {"$sort": {"len_list_of_items": -1}}, 
]) 
0

Для вашего первого запроса используйте аннотацию, как сказал вам в своем комментарии Умут Гунебакан. Но я знаю, уверен, что Count() на ListField

departments = DepartmentStats.objects.all().annotate(num_list_users=Count('list_of_users')).order_by('-num_list_users') 

Для заказа по убыванию по, вам просто нужно добавить знак «-» (минус). https://docs.djangoproject.com/en/1.10/ref/models/querysets/#order-by

Второй запрос будет:

departments = DepartmentStats.objects.all().annotate(user_per_workstation=(Count('list_of_users')/Count('list_of_workstations')).order_by('-user_per_workstation') 

UPDATE: (Mongoengine используется)

С mongoengine вам нужно получить частоты запись и отсортировали результат: Установите этот флажок, часть documentation - futher aggregation

list_user_freqs = DepartmentStats.objects.item_frequencies('list_of_users', normalize=True) 

from operator import itemgetter 
list_user_freqs_sroted = sorted(list_user_freqs.items(), key=itemgetter(1), reverse=True) 
+0

QuerySets Mongoengine не имеет такого атрибута, как 'annotate' – TitanFighter

+0

Я редактирую свой ответ после некоторых исследований в документации mongoengine. Вы можете попробовать? – Wilfried

Смежные вопросы