如何在Python中连接来自两个MongoDB集合的数据?

如何在Python中连接来自两个MongoDB集合的数据?,python,mongodb,pymongo,Python,Mongodb,Pymongo,作为学习练习,我正在Flask+MongoDB(w/pymongo)中制作一个迷你twitter克隆,我需要一些帮助来连接两个集合中的数据。我知道并理解连接不能在MongoDB中完成,这就是为什么我要问如何在Python中完成连接 我有一个集合来存储用户信息。文档如下所示: { "_id" : ObjectId("51a6c4e3eedc89e34ee46e32"), "email" : "alex@email.com", "message" : [ Ob

作为学习练习,我正在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”中的用户“\u id”的引用,反之亦然,对用户文档中“消息”中的消息“\u id”的引用

基本上,我想做的是获取每条消息的“author_id”,从用户集合中获取相应的用户名,并创建一个包含“username”+“text”+“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()输出相同的字典格式,并将它们合并以获得与上面相同的输出

这就是我被困的地方。我不知道该如何着手解决这个问题。感谢您的帮助

谢谢。

附加(“\u id”,“author\u id”),以便使用此id按预期检索相应的消息和author\u 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())))

您是否考虑过邮件中的用户名?它使阅读更容易,而且您可能不允许用户更改其姓名。即使你这样做了,你也可以在名字变更时更新所有文档。是的,我更新了。实际上,我在决定使用这个模式之前尝试了几种不同的模式。我选择这一个的原因之一是,如果这不仅仅是一个学习练习,我希望用户能够更改他们的用户名,所以我想最好现在就学习如何操作。另外,我之所以选择它,是因为objectid与存储字符串相比非常小(只有12个字节)。更多信息请点击这里:干杯!哇!我确认这是有效的。我真不敢相信修复这么简单。非常感谢你。
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())))