Python - sort mongodb by single key value

I have a collection with a lower data structure:

[{name: "123", category: "A"}, {name: "456", category: "B"}, {name: "789", category: "A"}, {name: "101", category: "C"}] 

I want to be able to sort them according to the category value, specifying what will be the first. For example, sorting a query in the order B-> C-> A, the result will give:

 [{name: "456", category: "B"}, {name: "101", category: "C"}, {name: "123", category: "A"}, {name: "789", category: "A"}] 

Is there a good way to do this with the mongo request APIs? I am using mongoengine

+4
source share
2 answers

The best way to do this is to use the .aggregate() method and $cond to add weight to your documents in $project , then use $sort sort the 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}] 
+2
source

I think it is not yet possible to provide a custom sort function in MongoDB:

You can, as a workaround, sort in Python by matching categories with numerical values โ€‹โ€‹that will actually be used to sort 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"]))) 
+1
source

Source: https://habr.com/ru/post/1240314/


All Articles