python - sort mongodb by the value of one key

烈酒焚心 提交于 2019-12-05 18:14:50

The best way to do this is using the .aggregate() method and the $cond conditional operator to add a weight to your documents in the $project stage then use the $sort aggregation operator to sort your documents by weight.

pipeline = [{'$project': {'category': 1,
               'name': 1,
               'w': {'$cond': [{'$eq': ['$category', 'B']},
                               1,
                               {'$cond': [{'$eq': ['$category', 'C']},
                                          2,
                                          3]
                               }]
                    }
            }},
            {'$sort': {'w': 1}}
]

Model.aggregate(*pipeline)

Demo using PyMongo:

>>> import pprint
>>> import pymongo
>>> client = pymongo.MongoClient()
>>> collection = client['test']['collection']
>>> pipeline = [{'$project': {'category': 1,
...                    'name': 1,
...                    'w': {'$cond': [{'$eq': ['$category', 'B']},
...                                    1,
...                                    {'$cond': [{'$eq': ['$category', 'C']},
...                                               2,
...                                               3]
...                                    }]
...                         }
...                 }},
...                 {'$sort': {'w': 1}}
...     ]
>>> pprint.pprint(list(collection.aggregate(pipeline=pipeline)))
[{'_id': ObjectId('571caa930e4f55302502a361'),
  'category': 'B',
  'name': '456',
  'w': 1},
 {'_id': ObjectId('571caa930e4f55302502a363'),
  'category': 'C',
  'name': '101',
  'w': 2},
 {'_id': ObjectId('571caa930e4f55302502a360'),
  'category': 'A',
  'name': '123',
  'w': 3},
 {'_id': ObjectId('571caa930e4f55302502a362'),
  'category': 'A',
  'name': '789',
  'w': 3}]

I think it is still not possible to provide a custom sorting function in MongoDB:

You can though, as a workaround, sort in Python, mapping categories to numerical values that would actually be used to sort the documents:

from pprint import pprint

weights = {
    "A": 2,
    "B": 0,
    "C": 1
}

docs = db.col.find()
pprint(sorted(docs, key=lambda item: weights.get(item["category"])))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!