2015-01-12 22 views
22

Jestem trochę zdezorientowany przez użycie Mongo DB z ObjectIds. Na pewno świetnie nadają się do tworzenia identyfikatorów po stronie klienta, które prawie na pewno nie kolidują z innymi identyfikatorami utworzonymi po stronie klienta. Ale mongo wydaje się przechowywać je w jakiś szczególny sposób. Przechowywanie reprezentacji ciągów o identyfikatorze to inny z zapisywania identyfikatora obiektu jako obiektu. Dlaczego to?Różnica między przechowywaniem ObjectId a jego ciągiem znaków w MongoDB

Czy ciąg znaków nie zawiera wszystkich tych samych informacji, które ma formularz obiektu? Dlaczego mongo idzie do takiej długości, aby odróżnić te dwie formy? Przykro mi, kiedy próbuję porównać _ids wysłany z frontendu na przykład. Moja baza danych nie jest w żaden sposób zgodna z tym, czy przechowuje identyfikatory łańcuchowe lub identyfikatory typu obiektu, a mój kod jest z pewnością częściowo winny, głównie obwiniam mongo za uczynienie tego tak dziwnym.

Czy jestem w błędzie, że to dziwne? Dlaczego mongo robi to w ten sposób?

Odpowiedz

15

Ja osobiście winię Twój kod. Obejmuję to doskonale w moich aplikacjach, kodując właściwy sposób. Konwertuję tekst na kod w celu porównania i gwarantuję, że wszystko, co wygląda jak ObjectId, jest używane jako ObjectId.

Dobrze jest pamiętać, że pomiędzy ObjectId (http://docs.mongodb.org/manual/reference/object-id/) i jest to reprezentacja hex jest w rzeczywistości 12 bajtów różnica, tym ObjectId wynosi 12 bajtów i jest hex reprezentacja jest 24.

jest nie tylko o wydajność pamięci, ale także o indeksach; nie tylko dlatego, że są mniejsze, ale także dlatego, że ObjectId może być używany w specjalny sposób, aby zapewnić załadowanie tylko części indeksu; części, które są używane. Jest to najbardziej zauważalne przy wstawianiu, gdzie tylko ostatnia część tego indeksu musi być załadowana, aby zapewnić wyjątkowość. Nie możesz zagwarantować takiego zachowania z jego reprezentacją w postaci szesnastkowej.

Zdecydowanie zaleca się, aby nie używać reprezentacji heksadecymalnej OjbectId. Jeśli chcesz "ułatwić sobie życie", lepiej byłoby stworzyć inny, mniejszy, ale w pewnym sensie równie unikalny i przyjazny dla indeksu.

+0

Nie powinieneś potrzebować konwertować obiektów ObjectIds na ciągi, aby je porównać. Mają metodę równości (przynajmniej w mangoskin). –

+0

Odwołanie, które powiedziałeś, że ObjectIds ma 12 bajtów, a nie 16 –

+0

@BT, co jest moim złym, musiał myśleć o czymś innym – Sammaye

3

ObjectId ma 12 bajtów, gdy jest przechowywany wewnętrznie, co jest bardziej kompaktowe niż reprezentacja szesnastkowego łańcucha znaków. Te dwie rzeczy są różne.

Możesz przywrócić swój cały DB i użyć jednolitego pola _id, aby rozwiązać ten problem i upewnić się, że kod zapisuje się w tym samym formacie. ObjectId są szybkie do wygenerowania przez MongoDB, więc użyłbym tego przy tworzeniu nowych dokumentów.

+0

Ach, więc to wszystko na temat wydajności przechowywania? Wszystkie moje _ids to ObjectIddy, ale dużo pól referencyjnych nie jest teraz, przypuszczam, że powinienem naprawić rzeczy. –

+1

Rozmiar pola również może wpłynąć na wydajność indeksowania/kwerendy (nie jestem pewny, ile za "ObjectId" kontra 'ObjectId.str ', ale MongoDB został prawdopodobnie zbudowany/przetestowany z ObjectId, więc użyjmy tego: D) – bakkal

+0

To jest naprawdę dość denerwujące, ponieważ nie ma naprawdę dobrego sposobu na przekształcenie identyfikatorów obiektów do postaci szeregowej. Wszelkie żądania pochodzące od klienta muszą być jawnie wyczesane, aby zastąpić identyfikatory łańcuchów identyfikatorami obiektów. Czy istnieje sposób na obejście tego? –