从Python mongodb中的列表中计算特定值

时间:2015-07-31 04:58:20

标签: python mongodb list mongodb-query aggregation-framework

我正在用MongoDB试验Python。我是python的新手。在这里,我从集合中获取记录,并根据该集合中的特定值,找到该记录的计数(来自第1个集合)。但我的问题是我无法将此计数添加到我的列表中。

以下是代码:

@gen.coroutine
def post(self):
    Sid = self.body['Sid']
    alpha = []
    test = db.student.find({"Sid": Sid})
    count = yield test.count()
    print(count)
    for document in (yield test.to_list(length=1000)):
        cursor = db.attendance.find({"StudentId": document.get('_id')})
        check = yield cursor.count()
        print(check)
        alpha.append(document)
    self.write(bson.json_util.dumps({"data": alpha}))

显示的输出alpha来自第一个集合(学生),计数值来自(出勤集合)。

当我尝试通过检查扩展列表时,我最终会出现错误

alpha.append(document.extend(check))

但是我在python终端中获得了正确的计数值,我无法将其与输出一起写入。

我的输出就像     {"data": [{"Sid": "1", "Student Name": "Alex","_id": {"$oid": "..."}}, {"Sid": "1", "Student Name": "Alex","_id": {"$oid": "..."}}]}

我的输出应该像

{"data": [{"Sid": "1", "Student Name": "Alex","_id": {"$oid": "..."},"count": "5"}, {"Sid": "1", "Student Name": "Alex","_id": {"$oid": "..."},"count": "3"}]}

请指导我如何获得所需的输出。

谢谢。

2 个答案:

答案 0 :(得分:1)

更好的方法是使用您正在使用的python驱动程序中的MongoDB .aggregate()方法,而不是重复.find().count()操作:

db.attendance.aggregate([
    { "$group": {
        "_id": "$StudentId",
        "name": { "$first": "$Student Name" },
        "count": { "$sum": 1 }
    }}
])

然后它已经为你完成了。

您当前的代码正在查找当前学生并返回"计数"有多少次出现。而且你是按照你的输出内容为每个学生做的。

而不是这样做,数据是"聚合"返回文档中的两个值以及" count"在返回的结果中,它是按学生汇总的。

这意味着您不需要为每个学生运行查询以获得计数。相反,你只需要调用数据库"一次"并在一个结果中统计你需要的所有学生。

如果您需要更多的学生而不是所有学生,那么您可以使用查询条件对其进行过滤;

db.attendance.aggregate([
    { "$match": { "StudentId": { "$in": list_of_student_ids } } },
    { "$group": {
        "_id": "$StudentId",
        "name": { "$first": "$Student Name" },
        "count": { "$sum": 1 }
    }}
])

选择以及聚合是为您完成的。

无需循环代码和大量数据库请求。 .aggregate()方法和管道将为您完成。

阅读Aggregation Pipeline上的核心文件。

答案 1 :(得分:0)

count条目添加到字典document并附加字典:

for document in (yield test.to_list(length=1000)):
    cursor = db.attendance.find({"StudentId": document.get('_id')})
    check = yield cursor.count()
    document['count'] = check
    alpha.append(document)