简体   繁体   English

如何从Python中的两个MongoDB集合中加入数据?

[英]How can I join data from two MongoDB collections in Python?

I'm making a mini twitter clone in Flask + MongoDB (w/ pymongo) as a learning exercise and I need some help joining data from two collections. 我正在使用Flask + MongoDB(w / pymongo)制作一个迷你推文克隆作为学习练习,我需要一些帮助来加入来自两个系列的数据。 I know and understand joins can't be done in MongoDB, that's why I'm asking how do it in Python. 我知道并理解联接不能在MongoDB中完成,这就是为什么我在问Python如何做到这一点。

I have a collection to store user information. 我有一个存储用户信息的集合。 Documents look like this: 文件看起来像这样:

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

and another collection to store messages (tweets): 和另一个存储消息的集合(推文):

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

As you can see, the message contains a reference to the user's "_id" in "author_id" in the message document and vice versa for the message's "_id" in "message" in the user document. 如您所见,消息包含对消息文档中“author_id”中用户的“_id”的引用,反之亦然,用户文档中“message”中的消息“_id”。

Basically, what I want to do is take every message's "author_id", get the corresponding username from the user collection and make a new dictionary containing the "username" + "text" + "pub_date". 基本上,我想要做的是将每条消息的“author_id”,从用户集合中获取相应的用户名,并创建一个包含“username”+“text”+“pub_date”的新字典。 With that, I could easily render the data in my Jinja2 template. 有了这个,我可以轻松地在我的Jinja2模板中渲染数据。

I have the following code that sorta do what I want: 我有以下代码,可以按照我想要的方式进行:

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())))

Output looks this: 输出看起来如下:

{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)}

Which is exactly what I want. 这正是我想要的。

The code doesn't work though because I'm doing .find_one() so I always get the first message even if a user has two or more. 代码不起作用,因为我正在做.find_one()所以我总是得到第一条消息,即使用户有两个或更多。 Doing .find() might resolve this issue, but .find() returns a cursor and not a dictionary like .find_one(). 执行.find()可能会解决此问题,但.find()返回游标而不是像.find_one()这样的字典。 I haven't figured out how to convert cursors to the same dictionary format as the output from .find_one() and merge them to get the same output as above. 我还没有弄清楚如何将游标转换为与.find_one()的输出相同的字典格式,并将它们合并以获得与上面相同的输出。

This is where I'm stuck. 这就是我被困住的地方。 I don't know how I should proceed to fix this. 我不知道如何解决这个问题。 Any help is appreciated. 任何帮助表示赞赏。

Thank you. 谢谢。

Append ("_id", "author_id") so that this id is used to retrive the corresponding message as expected and author_id to get username. 追加(“_ id”,“author_id”),以便此id用于按预期方式检索相应的消息,并使用author_id获取用户名。

You just need unique key to do that : 您只需要使用唯一键即可:

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())))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM