0

通过什么在 MongoDB(python、motor)中发出这种请求?

有一个文档集。有必要按以下顺序将它们显示在一个列表中:

  1. 先急。
  2. 进一步未兑现。
  3. 进一步的剩菜按日期从最近到最旧排序。

我制作了这样的工作解决方案,但我正在寻找如何将其优化为单个查询而不是三重查询并在 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)])

我也尝试过聚合,但似乎没有帮助

4

0 回答 0