2012-03-20 19 views
7

Potrzebuję przeczytać całą kolekcję z MongoDB (nazwa kolekcji to "test") w kodzie Pythona. Próbowałem jakJak czytać kolekcję w kawałkach przez 1000?

self.__connection__ = Connection('localhost',27017) 
    dbh = self.__connection__['test_db']    
    collection = dbh['test'] 

Jak odczytać poprzez gromadzenie w kawałkach o 1000 (w celu uniknięcia przepełnienia pamięci, ponieważ kolekcja może być bardzo duże)?

Odpowiedz

5

Użyj kursorów. Kursory mają zmienną "batchSize", która kontroluje, ile dokumentów jest faktycznie wysyłanych do klienta na partię po wykonaniu zapytania. Nie musisz dotykać tego ustawienia, ponieważ domyślne ustawienie jest w porządku, a złożoność, jeśli wywołanie poleceń "getmore" jest ukryte przed większością sterowników. Nie jestem zaznajomiony z pymongo ale to działa tak:

cursor = db.col.find() // Get everything! 

while(cursor.hasNext()) { 
    /* This will use the documents already fetched and if it runs out of documents in it's local batch it will fetch another X of them from the server (where X is batchSize). */ 
    document = cursor.next(); 

    // Do your magic here 
} 
+1

Jak to zrobić w Pythonie? –

5

zgadzam się z Remon, ale trzeba wspomnieć partii 1000, który jego odpowiedź nie naprawdę pokrycie. Można ustawić wielkość partii na kursora:

cursor.batch_size(1000); 

Można również pominąć rekordy, np .:

cursor.skip(4000); 

Czy tego szukasz? Jest to faktycznie wzór paginacji. Jeśli jednak próbujesz uniknąć wyczerpania pamięci, nie musisz ustawiać rozmiaru wsadu ani pominąć.

0

Do tworzenia połączenia początkowego obecnie w Pythonie 2 korzystając Pymongo:

host = 'localhost' 
port = 27017 
db_name = 'test_db' 
collection_name = 'test' 

Aby połączyć się przy użyciu MongoClient

# Connect to MongoDB 
client = MongoClient(host=host, port=port) 
# Make a query to the specific DB and Collection 
dbh = client[dbname] 
collection = dbh[collection_name] 

Więc stąd prawidłowej odpowiedzi. Chcę przeczytać za pomocą fragmentów (w tym przypadku o rozmiarze 1000).

chunksize = 1000 

Na przykład możemy zdecydować się ilu kawałki wielkości (chunksize) chcemy.

# Some variables to create the chunks 
skips_variable = range(0, db_aux[collection].find(query).count(), int(chunksize)) 
if len(skips_variable)<=1: 
    skips_variable = [0,len(skips_variable)] 

Następnie możemy pobrać każdą porcję.

for i in range(1,len(skips_variable)): 

    # Expand the cursor and retrieve data 

    data_from_chunk = dbh[collection_name].find(query)[skips_variable[i-1]:skips_variable[i]])) 

Gdzie zapytanie w tym przypadku to query = {}.

Here Używam podobnych pomysłów do tworzenia ramek danych z MongoDB. Here Używam czegoś podobnego do pisania na MongoDB w kawałkach.

Mam nadzieję, że to pomaga.