2016-09-01 6 views
3

Ich möchte die Anzahl der Dokumente in einer Mongong-Bson-Datei berechnet, ohne die Datei über Mongo Restore in die Datenbank importieren müssen.Zählen Sie schnell die Anzahl der Objekte in Bson-Dokument

Das Beste, was ich habe in der Lage gewesen, mit in Python zu kommen ist

bson_doc = open('./archive.bson','rb') 
it = bson.decode_file_iter(bson_doc) 
total = sum(1 for _ in it) 
print(total) 

Dieses in der Theorie funktioniert, aber langsam in der Praxis ist, wenn BSON Dokumente groß sind. Jeder hat einen schnelleren Ansatz, um die Anzahl der Dokumente in einem bson-Dokument zu zählen, ohne eine vollständige Decodierung durchzuführen?

Ich benutze derzeit die Python 2.7 und Pymongo.

+0

welche BSON Paket sind verwendest du? ist das der mongodb bson oder ein anderer? – 16num

+0

aktualisiert die Frage mit dieser Information. Das Bson-Paket, das ich verwende, ist das folgende https://api.mongodb.com/python/current/api/bson/index.html – user1438162

Antwort

2

Ich habe keine Datei zur Hand, aber ich glaube, es gibt einen Weg - wenn Sie die Daten von Hand analysieren.

Die source for bson.decode_file_iter (sans die docstring) geht so:

_UNPACK_INT = struct.Struct("<i").unpack 

def decode_file_iter(file_obj, codec_options=DEFAULT_CODEC_OPTIONS): 
    while True: 
     # Read size of next object. 
     size_data = file_obj.read(4) 
     if len(size_data) == 0: 
      break # Finished with file normaly. 
     elif len(size_data) != 4: 
      raise InvalidBSON("cut off in middle of objsize") 
     obj_size = _UNPACK_INT(size_data)[0] - 4 
     elements = size_data + file_obj.read(obj_size) 
     yield _bson_to_dict(elements, codec_options) 

Ich nehme an, der zeitraubende Vorgang ist _bson_to_dict Anruf - und Sie brauchen nicht ein.

Also, alles, was Sie brauchen, ist die Datei zu lesen - Holen Sie den Int32-Wert mit der nächsten Dokumentgröße und überspringen Sie es. Zählen Sie dann, wie viele Dokumente Ihnen dabei begegnet sind.

So, glaube ich, sollte diese Funktion den Trick:

import struct 
import os 
from bson.errors import InvalidBSON 

def count_file_documents(file_obj): 
    """Counts how many documents provided BSON file contains""" 
    cnt = 0 
    while True: 
     # Read size of next object. 
     size_data = file_obj.read(4) 
     if len(size_data) == 0: 
      break # Finished with file normaly. 
     elif len(size_data) != 4: 
      raise InvalidBSON("cut off in middle of objsize") 
     obj_size = struct.Struct("<i").unpack(size_data)[0] - 4 
     # Skip the next obj_size bytes 
     file_obj.seek(obj_size, os.SEEK_CUR) 
     cnt += 1 
    return cnt 

(.. Ich habe den Code nicht getestet, obwohl Sie haben nicht MongoDB zur Hand)

+0

Nur Zusatz zu Ihrer Funktion war, 'Struktur zu importieren' - https: //docs.python .org/2/library/struct.html # – user1438162

+0

Ja, plus einige weitere Importe ('os.SEEK_CUR' und' InvalidBSON' Ausnahme). Ich habe die Antwort bearbeitet. – drdaeman

+0

@ user1438162 Sie können eine kleine zusätzliche Beschleunigung haben, wenn Sie 'struct.Struct (" drdaeman

Verwandte Themen