我正在使用Flask + MongoDB(w / pymongo)制作一个迷你推文克隆作为学习练习,我需要一些帮助来加入来自两个馆藏的数据。我知道并且理解联接不能在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”的引用,反之亦然,在用户文档的“message”中包含消息“_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()的输出相同的字典格式,并将它们合并以获得与上面相同的输出。
这就是我被困住的地方。我不知道如何解决这个问题。任何帮助表示赞赏。
谢谢。
答案 0 :(得分: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())))