Klucz encji dla mongodb

0

Trochę eksperymentuje z Mongo w którym nigdy na produkcji nie pracowałem i coś tam sobie klepie na własne potrzeby. Mam Spring Data Mongo żeby nie klepać CRUDa i jakieś tam Encje do zapisywania danych. Jako że Mongo automatycznie generuje dla każdego dokumentu ObjectId postanowiłem to wykorzystać jako identyfikatory modeli po stronie Javy

    @Id
    private ObjectId id;

aczkolwiek tak się zastanawiam czy to na pewno jest wporządku? Mam wrażenie że wyciągam bebechy bazodanowe i zastanawiam się czy nie lepszym pomysłem byłoby utworzenie jakiegoś nowego Id typu np. Long i dać mu tam auto generowanie? Czy tak jest jednak okej i nawet jak potrzebuję to mogę sobie tym pluć na frontend?

0

W przypadku innej bazy też byś ID mapował do innego typu?
Ja osobiście zwracam ObjectId do frontu, tylko mam customowy JsonConverter żeby to jakoś normalnie wyglądało, nie wiem czy to jest najlepsze podejście ale nie widzę w tym problemów.

0

Na fronted nie powinno pluć sie modeli bazodanowych (no chyba że to prosty CRUD). Ja bym jednak użył Integera czy Longa jako klucz :)

0

U nas używamy tych ObjectID jako indentyfikatorów (no chyba, że coś ma jakiś naturalny identyfikator), front widzi to jako napisy - nie ma dla niego znaczenia czy tam jest GUUID czy ObjectId czy napis w stylu "JAKJIRA-101".
Wada jest taka, że zależność do BSON wygląda dziwnie w miejscach, które z bazą danych nie mają nic wspólnego.

0

Czyli w zasadzie każdy robi inaczej i ciężko zdecydować co jest bardziej poprawne ;)

0

Ja korzystam z generatora IDków zanim obiekt zostanie zapisany do bazy i trzymam to jako String - spring mongo świetnie to rozumie, wystarczy adnotacja @Id. Ten sam ID leci też do innych storage'ów np. elastic. Jeżeli to ci nie odpowiada lub odpowiada ci ObjectId to nie ma w tym nic złego, wszak to też jest String, wystarczy oddzielić warstwę persystencji od warstwy logiki i nic nie musi wiedzieć czy twój klucz jako String zawsze jest Stringiem czy może gdzieś pod spodem to ObjectId. Ew. możesz po prostu zrobić jak kolega wyżej napisał i mieć napisany konwerter, który chociaż przed frontem ukrywa prawdziwą postać IDka.

Czyli w zasadzie każdy robi inaczej i ciężko zdecydować co jest bardziej poprawne

Tak, tylko tak jak pisałeś nie ma co wyciągać bebechów na widok publiczny ;)

0
hcubyc napisał(a):

Ja korzystam z generatora IDków zanim obiekt zostanie zapisany do bazy i trzymam to jako String - spring mongo świetnie to rozumie, wystarczy adnotacja @Id. Ten sam ID leci też do innych storage'ów np. elastic.

@hcubyc Póki co poszedłem dokładnie w te stronę. Zależność od ObjectId w całej aplikacji wygląda mega słabo i trochę tak jakby gdzieś ta logika wyciekała. Zmieniłem to więc na String i dodałem @Id a Mongo nawet się nie zająknął. Po stronie bazy nadal jest to ObjectId więc wszystko gra tak jak należy.

hcubyc napisał(a):

Tak, tylko tak jak pisałeś nie ma co wyciągać bebechów na widok publiczny ;)

Właśnie to mi jedynie nie pasuje... Mam np. kategorie które mają jakieś nazwy i IDki. Tworząc np. artykuł potrzebuję id kategorii do jakiej został przypisany. Aktualnie wygląda to tak że zaciągana jest lista kategorii z IDkami na front, tworzony jest artykuł a potem wysyłam go na endpoint do zapisu artykułów między innymi z ID kategorii.

Teoretycznie jest spoko ale trochę sam nie wiem co myśleć. Z jednej strony jest to identyfikator bazodanowy więc właściwie to trochę wypluwam bebechy bazodanowe.
Z drugiej jednak strony jedyne co mogę zrobić to dodać nowe pole które będzie jakimś Longiem czy UUID i będzie takim powiedzmy publicznym ID do wiązania z innymi encjami. Pytanie tylko czym tak naprawdę ten powiedzmy UUID będzie się różnił od ObjectId? W zasadzie tylko tym że ObjectId jest "primary key". Jeden i drugi jest częścią bazy danych i oba muszą być unikatowe. Jedyna korzyść jaką widzę to to że nie wyciągam na zewnątrz identyfikatora bazodanowego tylko wygenerowane samodzielnie. Pytanie tylko czy to coś zmienia i czy w ogóle ma sens?

1

Pytanie tylko czy to coś zmienia i czy w ogóle ma sens?

Moim zdaniem nie. Mi chodziło tylko o to, by nie pchać na front objectId jako obiektu, bo jezeli dobrze pamiętam to obiekt z polem w środku. Jeżeli dobrze cie zrozumiałem i rozważasz utworzenie jakiegoś połaczenia miedzy IDkiem, który sam nadajesz, a ObjectID to IMHO nie ma to sensu. Posługiwanie się IDkiem bazodanowym to nic złego, generalnie skąd user ma wiedziec skąd jest ten ID (czy sam go wygenerowaleś czy baza ci wygenerowała) i zreszta co go to obchodzi - jest jakiś identyfikator, który gwarantuje unikalność w ogóle lub w obrębie danego typu w zalezności od potrzeb i to jest istotne, to skąd jest już nie. Zależy jak wygląda twoja logika u mnie jest tak, że najpierw generuję IDka, a potem ten ID jest pchany do różnych źródeł, ale tak samo mozna zrobić z ObjectId, tylko najpierw trzeba zapisać dokument w mongo by go dostac, jedyna różnica. Może istnieć szansa, że jakaś baza słabo obsługuje primary key jako string, a nie np. liczby, ale jeżeli teraz cię do nie dotyczy to bym się tym nie martwił.

0

tak samo mozna zrobić z ObjectId, tylko najpierw trzeba zapisać dokument w mongo by go dostac

Eee, nie. Nie trzeba niczego najpierw zapisywać do bazy. Można robić ObjectId.get(), żeby dostać świeży identyfikator przed zapisaniem danych w bazie. Równie dobrze tam mógłby być UUID,random(). Ze dwa razy przydał się fakt, że ObjectId ma zaszyty timestamp i można było odfiltrować dokumenty stworzone w określonym przedziale mimo braku tradycyjnych pól audytu.

0
hcubyc napisał(a):

Posługiwanie się IDkiem bazodanowym to nic złego, generalnie skąd user ma wiedziec skąd jest ten ID (czy sam go wygenerowaleś czy baza ci wygenerowała) i zreszta co go to obchodzi - jest jakiś identyfikator, który gwarantuje unikalność w ogóle lub w obrębie danego typu w zalezności od potrzeb i to jest istotne, to skąd jest już nie.

Kiedyś czytałem że nie powinno się ujawniać bazodanowych PK bo jest to pewnego rodzaju logika naszej aplikacji która lepiej aby była ukryta przed użytkownikiem. Mogłoby się zdarzyć że jeśli są jakieś luki w systemie to ciekawski użytkownik mając taki identyfikator móglby wyciągnąć sobie wiele innych informacji (korzystając z tego że relacyjne bazy danych to struktura mesh). Jakby się tak jednak zastanowić to tak naprawdę w takiej sytuacji problemem nie jest ujawniony ID tylko luka w systemie. Po drugie jeśli PK zostawimy ukryty a dodamy jakiś ręcznie generowany public id to przecież on też musi być unikatowy i wracając do przykładu z luką w systemie nadal można by sobie dociągnąć wiele danych.

Tak czy inaczej @hcubyc myślę że Twoja wypowiedź w pełni wyczerpuje temat, więc po stronie logiki i bazy posługuję się ObjectId a jak robię jakieś query to na front pluję Stringiem. Wygląda i działa dobrze więc co raz bardziej podoba mi się to Mongo :)!

1 użytkowników online, w tym zalogowanych: 0, gości: 1