5

我正在 Flask + MongoDB (w/pymongo) 中制作一个迷你 twitter 克隆作为学习练习,我需要一些帮助来连接来自两个集合的数据。我知道并理解无法在 MongoDB 中完成连接,这就是为什么我要问如何在 Python 中完成连接。

我有一个集合来存储用户信息。文档如下所示:

{
    "_id" : ObjectId("51a6c4e3eedc89e34ee46e32"),
    "email" : "alex@email.com",
    "message" : [
        ObjectId("51a6c5e1eedc89e34ee46e36")
    ],
    "pw_hash" : "alexhash",
    "username" : "alex",
    "who_id" : [
        ObjectId("51a6c530eedc89e34ee46e33"),
        ObjectId("51a6c54beedc89e34ee46e34")
    ],
    "whom_id" : [ ]
}

和另一个存储消息(推文)的集合:

{
    "_id" : ObjectId("51a6c5e1eedc89e34ee46e36"),
    "author_id" : ObjectId("51a6c4e3eedc89e34ee46e32"),
    "text" : "alex first twit",
    "pub_date" : ISODate("2013-05-30T03:22:09.462Z")
}

如您所见,消息在消息文档的“author_id”中包含对用户“_id”的引用,反之亦然,在用户文档的“消息”中包含对消息的“_id”的引用。

基本上,我想要做的是获取每条消息的“author_id”,从用户集合中获取相应的用户名,并制作一个包含“用户名”+“文本”+“pub_date”的新字典。有了它,我可以轻松地在我的 Jinja2 模板中呈现数据。

我有以下代码可以做我想做的事:

def getMessageAuthor():
    author_id = []
    # get a list of author_ids for every message
    for author in coll_message.find():
        author_id.append(author['author_id'])
    # iterate through every author_ids to find the corresponding username
    for item in author_id:
        message = coll_message.find_one({"author_id": item}, {"text": 1, "pub_date": 1})
        author = coll_user.find_one({"_id": item}, {"username": 1})
        merged = dict(chain((message.items() + author.items())))

输出如下:

{u'username': u'alex', u'text': u'alex first twit', u'_id': ObjectId('51a6c4e3eedc89e34ee46e32'), u'pub_date': datetime.datetime(2013, 5, 30, 3, 22, 9, 462000)}

这正是我想要的。

该代码不起作用,因为我正在做 .find_one() 所以即使用户有两个或更多,我总是会收到第一条消息。执行 .find() 可能会解决此问题,但 .find() 返回的是游标,而不是像 .find_one() 这样的字典。我还没有弄清楚如何将游标转换为与 .find_one() 的输出相同的字典格式并将它们合并以获得与上面相同的输出。

这就是我卡住的地方。我不知道我应该如何着手解决这个问题。任何帮助表示赞赏。

谢谢你。

4

1 回答 1

3

追加 ("_id", "author_id") 以便使用此 id 按预期检索相应的消息,并使用 author_id 获取用户名。

您只需要唯一的密钥即可:

def getMessageAuthor():
    author_id = []
    # get a list of ids and author_ids for every message
    for author in coll_message.find():
        author_id.append( (author['_id'], author['author_id']))
    # iterate through every author_ids to find the corresponding username
    for id, item in author_id:
        message = coll_message.find_one({"_id": id}, {"text": 1, "pub_date": 1})
        author = coll_user.find_one({"_id": item}, {"username": 1})
        merged = dict(chain((message.items() + author.items())))
于 2013-05-31T05:32:18.267 回答