通过什么在 MongoDB(python、motor)中发出这种请求?
有一个文档集。有必要按以下顺序将它们显示在一个列表中:
- 先急。
- 进一步未兑现。
- 进一步的剩菜按日期从最近到最旧排序。
我制作了这样的工作解决方案,但我正在寻找如何将其优化为单个查询而不是三重查询并在 MongoBD 端添加分页?:
now = datetime.utcnow()
reactivated = db.vtodo.find({'next_time': {'$lt': now},
"project": project}).sort([("is_project", -1)])
uncompleted = db.vtodo.find({"project": project,
'completed': None}).sort([("is_project", -1)])
completed_new_old = db.vtodo.find(
{"project": project, 'completed': {'$ne': None},
'$or': [{'next_time': {'$gt': now}}, {'next_time': None}]}).sort(
[("is_project", -1), ("completed", -1), ])
reactivated = await reactivated.to_list(length=await db.vtodo.count_documents({}))
uncompleted = await uncompleted.to_list(length=await db.vtodo.count_documents({}))
completed_new_old = await completed_new_old.to_list(
length=await db.vtodo.count_documents({}))
vtodos = reactivated + uncompleted + completed_new_old
page = 0
size = 12
return vtodos[page * size: page * size + size]
文档示例:
[{'_id': ObjectId('6096988f8d23679184d619a3'), 'title': 'T5',
'creator': ObjectId('6077f7207610f32a8d5e7e0c'),
'completed': datetime.datetime(2021, 6, 5, 8, 30, 16, 631000),
'next_time': datetime.datetime(2021, 6, 6, 8, 30, 16),
'project': ObjectId('60aba9b03a686ce60be89538')}]
[{'_id': ObjectId('60abd6a487bdf6655a393388'), 'title': 'T6',
'creator': ObjectId('6077f7207610f32a8d5e7e0c'), 'is_project': True,
'project': ObjectId('60aba9b03a686ce60be89538')},
{'_id': ObjectId('60be85006a5355235313575e'), 'title': 'T1',
'creator': ObjectId('6077f7207610f32a8d5e7e0c'),
'project': ObjectId('60aba9b03a686ce60be89538'),
'next_time': datetime.datetime(2021, 6, 8, 23, 44, 26)},
{'_id': ObjectId('60be85016a5355235313575f'), 'title': 'T2',
'creator': ObjectId('6077f7207610f32a8d5e7e0c'),
'project': ObjectId('60aba9b03a686ce60be89538')}]
[{'_id': ObjectId('60be85056a53552353135761'), 'title': 'T4',
'creator': ObjectId('6077f7207610f32a8d5e7e0c'),
'project': ObjectId('60aba9b03a686ce60be89538'),
'completed': datetime.datetime(2021, 6, 7, 20, 44, 10, 882000), 'next_time': None},
{'_id': ObjectId('60be85036a53552353135760'), 'title': 'T3',
'creator': ObjectId('6077f7207610f32a8d5e7e0c'),
'project': ObjectId('60aba9b03a686ce60be89538'),
'completed': datetime.datetime(2021, 6, 7, 20, 44, 3, 168000), 'next_time': None}]
预期结果:
T5,
T6,
T1,
T2,
T4,
T3
更新:尝试使用$or
,但结果完全无序:
db.vtodo.find({'$or': [
{"creator": oid, 'next_time': {'$lt': now}, "project": None},
{"creator": oid, "project": None, 'completed': None},
{"creator": oid, "project": None}, ]}).sort(
[("is_project", -1)])
我也尝试过聚合,但似乎没有帮助