Mongodb 使用PyMongo,我需要获取另一个集合的字段

Mongodb 使用PyMongo,我需要获取另一个集合的字段,mongodb,python-2.7,mongodb-query,jupyter-notebook,pymongo-2.x,Mongodb,Python 2.7,Mongodb Query,Jupyter Notebook,Pymongo 2.x,我需要使用PyMongo构造一个查询,它从MongoDB数据库中的两个相关集合获取数据 集合X具有UserId、Name和EmailId字段: [ { “用户ID”:“941AB”, “姓名”:“Alex Andresson”, “电子邮件ID”:”alex@example.com" }, { “用户ID”:“768CD”, “姓名”:“布莱恩·巴恩斯”, “电子邮件ID”:”bryan@example.com" } ] 集合Y具有UserId1、UserID2和Rating字段: [

我需要使用PyMongo构造一个查询,它从MongoDB数据库中的两个相关集合获取数据

集合X具有UserId、Name和EmailId字段:

[
{
“用户ID”:“941AB”,
“姓名”:“Alex Andresson”,
“电子邮件ID”:”alex@example.com"
},
{
“用户ID”:“768CD”,
“姓名”:“布莱恩·巴恩斯”,
“电子邮件ID”:”bryan@example.com"
}
]   
集合Y具有UserId1、UserID2和Rating字段:

[
{
“UserId1”:“941AB”,
“UserId2”:“768CD”,
“评级”:0.8
}
]
我需要打印UserId1和UserId2的名称和电子邮件id以及评级,如下所示:

[
{
“UserId1”:“941AB”,
“用户名1”:“Alex Andresson”
“UserEmail1”:alex@example.com",
“UserId2”:“768CD”,
“用户名2”:“布莱恩·巴恩斯”
“UserEmail2”:bryan@example.com",
“评级”:0.8
}
]

这意味着我需要从集合Y和集合X中获取数据。我现在正在和PyMongo合作,我还没有找到它的解决方案。有人能给我一个关于这个概念或方法的伪代码吗?

你需要手动进行连接,或者使用一些库来为你做-也许

基本上,你需要找到你感兴趣的评分,然后找到与这些评分相关的用户

例如:

#!/usr/bin/env python3

import pymongo
from random import randrange

client = pymongo.MongoClient()
db = client['test']

# clean collections
db['users'].drop()
db['ratings'].drop()

# insert data
user_count = 100
rating_count = 20

db['users'].insert_many([
    {'UserId': i, 'Name': 'John', 'EmailId': i}
    for i in range(user_count)])

db['ratings'].insert_many([
    {'UserId1': randrange(user_count), 'UserId2': randrange(user_count), 'Rating': i}
    for i in range(rating_count)])

# don't forget the indexes
db['users'].create_index('UserId')
# but it would be better if we used _id as the UserId

# if you want to make queries based on Rating value, then add also this index:
db['ratings'].create_index('Rating')

# now print ratings with users that have value 10+

# simple approach:
ratings = db['ratings'].find({'Rating': {'$gte': 10}})
for rating in ratings:
    u1 = db['users'].find_one({'UserId': rating['UserId1']})
    u2 = db['users'].find_one({'UserId': rating['UserId2']})
    print('Rating between {} (UserId {:2}) and {} (UserId {:2}) is {:2}'.format(
        u1['Name'], u1['UserId'], u2['Name'], u2['UserId'], rating['Rating']))

print('---')

# optimized approach:
ratings = list(db['ratings'].find({'Rating': {'$gte': 10}}))
user_ids = {r['UserId1'] for r in ratings}
user_ids |= {r['UserId2'] for r in ratings}
users = db['users'].find({'UserId': {'$in': list(user_ids)}})
users_by_id = {u['UserId']: u for u in users}
for rating in ratings:
    u1 = users_by_id.get(rating['UserId1'])
    u2 = users_by_id.get(rating['UserId2'])
    print('Rating between {} (UserId {:2}) and {} (UserId {:2}) is {:2}'.format(
        u1['Name'], u1['UserId'], u2['Name'], u2['UserId'], rating['Rating']))
请注意,第一种方法为评级调用一个
find
,为每个评级调用两个
find
s,但第二种方法总共只调用三个
find
s。如果您通过网络访问MongoDB,这将导致巨大的性能差异

如果可能,我建议在用户集合中使用
\u id
而不是
UserId

当然,使用SQL数据库,这个特定的用例会容易得多。如果您正在使用MangGDB来实现性能,并且您的读比写多很多,那么就可以考虑将相关的用户名输入到评级文档中。