3

MongoDB データベース内の 2 つの関連するコレクションからデータを取得する PyMongo を使用して、クエリを作成する必要があります。

コレクション 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、および Rating があります。

[
  {
    "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 を使用していますが、その解決策を見つけることができませんでした。誰かがこの概念に関する疑似コードを教えてくれたり、それを進める方法を教えてくれませんか?

4

1 に答える 1

0

手動で参加を行うか、それを行うライブラリを使用する必要があります - おそらく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最初のアプローチでは評価用に 1 つ、評価findごとに 2 つの が呼び出されますが、2 番目のアプローチfindでは合計で 3 つのしか呼び出されないことに注意してください。これにより、ネットワーク経由で MongoDB にアクセスしている場合、パフォーマンスに大きな違いが生じます。

users コレクションには、可能であれば_id代わりに使用することをお勧めします。UserId

もちろん、この特定の使用例は、SQL データベースを使用するとはるかに簡単になります。パフォーマンスのために MongoDB を使用していて、書き込みよりも読み取りの方がはるかに多い場合は、関連するユーザー名を評価ドキュメントにキャッシュすることを検討してください。

于 2016-08-19T18:20:01.790 に答える