Запись огромного набора результатов Mongo на диск с Python дружественным способом - PullRequest
1 голос
/ 25 сентября 2011

В коллекции Монго более 5 миллионов предметов. Мне нужно получить «представление» (хранящееся в переменной или помещенное в файл на диске, что-нибудь в этом месте) одного атрибута всех «документов».

Мой запрос выглядит примерно так:

cursor = db.collection.find({"conditional_field": {"subfield": True}}, {"field_i_want": True})

Моей первой глупой попыткой было засечь «курсор», но я быстро понял, что это так не работает.

В этом случае «field_i_want» содержит целое число. И в качестве примера того, что я попробовал, я сделал это и практически заблокировал сервер на несколько минут:

ints = [i['field_i_want'] for i in cursor]

... просто чтобы получить список целых чисел. Это слишком долго загружало ресурсы процессора на сервере.

Существует ли удаленно простой способ извлечения этих результатов в список, кортеж, набор, маринование, файл, что-то, что не полностью загружает процессор? В идеале я мог бы выбросить результаты, которые будут прочитаны позже. Но я бы хотел быть настолько добрым, насколько это возможно, когда бросал их.

Ответы [ 2 ]

1 голос
/ 25 сентября 2011

Я думаю, что потоковые результаты, вероятно, помогут здесь:

with open("/path/to/storage/file", "w") as f:
    for row in cursor:
        f.write(row['your_field'])

Не храните все в памяти, если вам не нужно.

0 голосов
/ 24 ноября 2011

Несмотря на то, что он уже принят, я бы добавил, что вы также можете рассмотреть возможность добавления индекса. Легко думать, что мы исчерпали «пропускную способность» монго, но это «монго» по причине! В зависимости от структуры вашей базы данных, 5 миллионов ответов могут быть совершенно быстрыми; Похоже, что в целом ваши данные будут около 5 миллионов целых чисел? Для простоты предположим, что field_i_want и т. Д. Являются переменными, содержащими имена полей. Если вы делаете:

db.collection.ensure_index([(conditional_field, DESCENDING), (field_i_want, ASCENDING)])

например, вы сможете выполнить «покрытый запрос», например:

db.collection.find({conditional_field:True},fields={field_i_want:1, _id:-1})

Иногда pymongo может произвольно решить, что ему нужно перевести словарь-синтаксис mongodb в список, как в случае с поле Туризм_index и полями выше. Я полагаю, что вы можете использовать словарь для полей, который необходим для покрытых запросов, но если нет, то вам нужно было бы изучить, как выполнять покрытые запросы с неудобным синтаксисом, используя список. Важная вещь в покрытом запросе - возвращать только те поля, которые являются частью вашего индекса. Так что вам не нужен «_id», потому что, хотя «_id» автоматически индексируется, он не является частью индекса, который будет использоваться. Не будет времени на выполнение запроса с закрытым запросом. Он просто передаст вам все данные, которые вы хотите мгновенно. Если вы предпочитаете использовать его в виде списка, а не списка словарей («документов»), вы можете просто взять ответ и сделать что-то вроде:

[y for x,y in myquery.items()]

Mongo - это уже двоичное представление, и оно хорошо хранит, так что это может быть один из тех вопросов, где лучший ответ - продолжать оттачивать вопрос. Если вы просто хотите получить дамп, вы можете использовать утилиты, которые поставляются с mongo и находятся в том же каталоге, что и ваш бинарный файл mongod. Это позволит вам получить ваши данные в json, сохраненные в виде файла (хотя, опять же, в настоящее время они хранятся в виде файла в bson).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...