我试图查询MongoDB数据库并将两组结果(' _id'和#39; Team')分成两个单独的列表。
import pymongo
client = pymongo.MongoClient('localhost:27017')
db = client['db_name']
query = {'Team': {'$exists': 1}}
projection = {'_id': 1, 'Team': 1}
data = db['collection_name'].find(query, projection) # line 9
id_list = [value for dict in data for key, value in dict.iteritems() if key == '_id']
teams_list = [value for dict in data for key, value in dict.iteritems() if key == 'Team']
print id_list
print teams_list
client.close()
对于上面的代码,' id_list'正如所料,但' teams_list'是空的。当我把'team_list'之前' id_list'我得到了预期的' teams_list'输出和' id_list'是空的。当我在两个列表推导之间重复数据调用(第9行)时,我得到两个列表的预期输出。
知道为什么会这样吗?
答案 0 :(得分:2)
您需要将data
定义为:
data = list(db['collection_name'].find(query, projection))
当find()
返回生成器时。一旦迭代了值,那些就会丢失。您需要将它们存储为list
。这里list()
执行该操作,即将生成器返回的项目存储为列表。
而不是迭代列表两次,更好的方法是两个单循环:
id_list, teams_list = [], []
# v `dict` is in-built data type, you should not be using it as variable
for d in data:
for key, value in d.iteritems():
if key == '_id':
id_list.append(value)
elif key == 'Team':
teams_list.append(value)
有关生成器的更多信息,请参阅Generator wiki
答案 1 :(得分:0)
如前所述,罪魁祸首是find()
方法,它返回一个>>> qs = (Track.objects
... .filter(listens__album=1294)
... .annotate(listen_count=models.Count('listens', distinct=True))
... .order_by('-listen_count')
... )
对象,当你第一次迭代时会消耗它。
但是你正在使用错误的方法来完成工作。您需要使用.aggregate()
方法。
SELECT
"music_track"."id",
"music_track"."name",
COUNT(DISTINCT "music_listen"."id") AS "listen_count"
FROM "music_track"
INNER JOIN "music_listen" ON ("music_track"."id" = "music_listen"."track_id")
WHERE "music_listen"."album_id" = 1294
GROUP BY "music_track"."id", "music_track"."name"
ORDER BY "listen_count" DESC
Cursor
方法与他的犯罪伙伴query = {'Team': {'$exists': 1}}
cursor = db['collection_name'].aggregate([
{'$match': query }
{ '$group': {
'_id': None,
'id_list': {'$push': '$_id'},
'teams_list': {'$push': '$Team'}
}}
])
一样,在结果集上返回CommandCursor
,这是一个像对象一样的生成器。
因为我们按.aggregate()
进行分组,所以迭代光标会生成一个文档,这意味着您可以放心地执行:
.find()
或
None