gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 09:54:38 26 4
gpt4 key购买 nike

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

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

[
{
"UserId" : "941AB",
"Name" : "Alex Andresson",
"EmailId" : "alex@example.com"
},
{
"UserId" : "768CD",
"Name" : "Bryan Barnes",
"EmailId" : "bryan@example.com"
}
]

集合 Y 具有字段 UserId1、UserID2 和评级:

[
{
"UserId1" : "941AB",
"UserId2" : "768CD",
"Rating" : 0.8
}
]

我需要打印 UserId1 和 UserId2 的名称和电子邮件 ID 以及评分,如下所示:

[
{
"UserId1" : "941AB",
"UserName1" : "Alex Andresson"
"UserEmail1" : "alex@example.com",
"UserId2" : "768CD",
"UserName2" : "Bryan Barnes"
"UserEmail2" : "bryan@example.com",
"Rating": 0.8
}
]

这意味着我需要从集合 Y 和 X 中获取数据。我现在正在使用 PyMongo,但我一直无法找到它的解决方案。有人甚至可以给我关于这个概念的伪代码或方法如何推进它。

最佳答案

您需要手动进行连接或使用一些可以为您完成的库 - 也许是 mongoengine .

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

例子:

#!/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,但第二种方法只调用三个 find总共。如果您通过网络访问 MongoDB,这将导致巨大的性能差异。

我建议尽可能使用 _id 而不是 UserId 来收集用户。

当然,使用 SQL 数据库这个特定用例会容易得多。如果您使用 MongoDB 来提高性能,并且读取次数多于写入次数,那么请考虑将相关用户名缓存到评级文档中。

关于mongodb - 使用 PyMongo,我需要获取另一个集合的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37720164/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com