2015-02-22 10 views
6

Próbuję zapisać słownik zawierający znak specjalny "." w kluczowej części do MongoDB. Błąd został przedstawiony poniżej, który wyraźnie stwierdza, że ​​klucz nie może zawierać znaku specjalnego ".".MongoDB nie zezwala na używanie "." w kluczu

>>> import pymongo 
>>> client = pymongo.MongoClient('localhost') 
>>> db = client['malware']                                       
>>> test = db['test'] 
>>> d = {'.aaa' : '.bbb'}                                       
>>> test.insert(d) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib64/python2.7/site-packages/pymongo/collection.py", line 362, in insert 
    self.database.connection) 
bson.errors.InvalidDocument: key '.aaa' must not contain '.' 

Ale moje bieżące informacje zawierają "." w kluczowej części danych, którą muszę przechowywać w MongoDB. Aktualnie właśnie kasowałem "." ze stringa, inną opcją byłoby zastąpienie go znakiem "_" lub innym specjalnym znakiem.

Niemniej jednak wszystkie skutkują utratą informacji, ponieważ jeśli mam klucz ".aa" i klucz "aaa" i jeśli konwertuję "." do "", wtedy klucze są dokładnie takie same i tracę trochę informacji. Dlaczego Mongo nie pozwala mi zapisać ".aa" w DB?

Jakieś pomysły, jak podejść do problemu?

Odpowiedz

10

Można ustawić check_keys False według source:

test.insert(d,check_keys=False) 


def insert(self, doc_or_docs, manipulate=True, 
      safe=None, check_keys=True, continue_on_error=False, **kwargs): 

Czyni rzeczywiście praca:

In [28]: d = {'.aaa' : '.bbb'} 

In [29]: test.insert(d,check_keys=False) 
Out[29]: ObjectId('54ea604bf9664e211e8ed4e6') 

Państwa docstring:

  • check_keys (opcjonalnie) : Jeśli True sprawdź, czy klucze zaczynają się od "$" lub zawierają ".", Podnosząc: klasa: ~pymongo.errors.InvalidName w obu przypadkach.

Wydajesz się być w stanie wykorzystać dowolny znak oprócz właśnie tak wiodącego podkreślenia dwóch $ lub . lub jakiegokolwiek innego znaku byłoby dobrze i prawdopodobnie lepszym rozwiązaniem.

Nie ma informacji w FAQ o escaping:

W niektórych przypadkach może chcesz zbudować obiekt BSON z kluczem użytkownika warunkiem. W takich sytuacjach klucze będą musiały zastąpić zastrzeżone $ i. postacie. Każdy znak jest wystarczający, ale należy rozważyć użycie odpowiedników pełnej szerokości Unicode: U + FF04 (tj. "$") I U + FF0E (tj. ".").

I FAQ dot-notacja wyjaśnia dlaczego używając . nie jest dobrym pomysłem:

MongoDB używa notacji dot dostępu do elementów tablicy i dostępu do pól osadzonym dokumentu. Aby uzyskać dostęp do elementu tablicy przez położenie indeksu od zera, złączyć nazwę tablicy z kropką i położenia indeksu od zera, i ująć w cudzysłów (.):

+0

Dziękuję za powiadomienie mnie o tej opcji. Czy możesz krótko opisać, dlaczego Mongo nie pozwoli ci zapisać klucza za pomocą "." domyślnie i musisz to przesłonić, aby to zrobić? To dałoby kompletną odpowiedź z faktycznym wyjaśnieniem, dlaczego tak się dzieje, a następnie mogę przyjąć tę odpowiedź jako poprawną. Dzięki jeszcze raz. – eleanor

+2

'insert()' jest przestarzałe, zastąpione 'insert_one()', które nie ma argumentu 'check_keys'. Ma argument "bypass_document_validation", ale nie ma tego samego efektu, nadal nie wstawi dokumentu, który ma kropkę w kluczu. –

2

nie można używać ".aaa" jako klucz, ponieważ Mongo używa kropki w odniesieniu do nested documents.

Jeśli chcesz mieć kluczową wyglądają jak kropki, można użyć odpowiednik unicode jak \u002E:

>>> d = {'\u002Eaaa' : '\u002Ebbb'}  

Jednak chciałbym zaproponować podejście po prostu wybierając inny charakter i przyjmując ją jako "ograniczenie" platformy.

Powiązane problemy