powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
25 сообщений из 78, страница 1 из 4
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39973937
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подключил к своему проекту MongoDB (Mongo Cloud) и складываю туда объекты в виде документов.

Репозиторий для общения с БД:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
@Repository
public interface GooglePlayGamesRepository extends MongoRepository <GooglePlayGame, String> {

    GooglePlayGame findByTitleIgnoreCase(String gameTitle);

    @Aggregation("{$sample: {size: ?0} }")
    List<GooglePlayGame> findRandomGames(Long amount);

    List<GooglePlayGame> findByTitleContainsIgnoreCase(String gameTitle);

}


Сам объект, который сохраняю:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
import org.springframework.data.annotation.Id;

@Document(collection = "googleplaygames")
@Getter
@Component
public final class GooglePlayGame implements Serializable {

    @Id
    String title; //это уникальный ключ!
    String genre;
    String price;
...
}



Если сохранять объект в таком виде, в коллекции MongoDB поле title заменяется на _id , а title просто становится null и никак не отображается в коллекции, так как если пробую добавить ещё одну игру, вылетает exception:
Код: java
1.
org.springframework.dao.DuplicateKeyException: E11000 duplicate key error collection: 5ef31a21233f9c398f473c6e_botapi.googleplaygames index: title dup key: { title: null };


Если убрать аннотацию @Id, то в коллекции будут храниться дубликаты и будет две одинаковых игры, у которых отличается поле "номер версии". Мне игра нужна в единственном экземпляре: если у игры, например, изменился номер версии, я хочу перезаписать этот объект (если он уже есть в БД) с новой версией.

Пробовал с помощью аннотации @Indexed(unique = true) на поле. В таком случае другие игры добавляются, но если я пробую перезаписать старый объект с таким же полем, то также получаю DuplicateKey.

Для сохранения в БД использую метод save.

Как быть? Писать ручками запрос?
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974038
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974134
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp
miroooha,

https://www.google.com/search?newwindow=1&client=tablet-android-huawei&ei=NHD5Xs3kBcHIrgTTwYDgDw&q=mongo cloud id primary key&oq=Mongo Cloud id primary&gs_lcp=ChNtb2JpbGUtZ3dzLXdpei1zZXJwEAEYADIFCCEQoAE6BAgAEEc6BAgAEAo6AggAOggIABAWEAoQHjoICCEQFhAdEB46BQgAEM0COgcIIRAKEKABUJ8xWM6zAWD9wgFoA3ABeACAAaIKiAHFJpIBDzAuMi41LjIuMC4xLjEuMZgBAKABAQ&sclient=mobile-gws-wiz-serp
?

Primary Key - это и есть аннотация @Id у меня в примере. И с ней не работает. Он смотрит, что я добавляю объект с таким же полем и тут же DuplicationError, не смотря на то, что другие поля уже отличаются.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974136
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В доках написано, что метод save работает как insert, если такого документа нет, и как update, если документ уже есть. Но кто-то меня обманывает, либо что-то недоговаривает. Никакого update у меня не происходит.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974145
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha,
Значит ссылку где обманывают сюда. И код тоже сюда.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974146
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha,
Там в веб в примере id строковый тип?
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974150
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp
miroooha,
Значит ссылку где обманывают сюда. И код тоже сюда.

https://www.concretepage.com/spring-5/spring-data-mongorepository-update#save

В подобных примерах в основном числовой тип, а не строковый. У меня же строка.

Да и этот метод save() наследуется от CrudRepository. И опять же, пишут, что он работает и как update, например тут:
https://www.baeldung.com/spring-data-crud-repository-save
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974179
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha,

>В подобных примерах в основном числовой тип, а не строковый. У меня же строка.
Вот и сделай числовой. И потом с примером сюда.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974279
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp
miroooha,

>В подобных примерах в основном числовой тип, а не строковый. У меня же строка.
Вот и сделай числовой. И потом с примером сюда.

А нафига мне числовой то? Если у меня поиск по названию игры. На кой черт мне вообще это число? :D Ввести доп.переменную числового типа и пометить её как primary key? Я попробую, но выглядит абсурдно.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974292
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha
А нафига мне числовой то? Если у меня поиск по названию игры. На кой черт мне вообще это число? :D Ввести доп.переменную числового типа и пометить её как primary key? Я попробую, но выглядит абсурдно
вообще-то это первое дело в таблицах иметь поде id primary key
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974293
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha
А нафига мне числовой то? Если у меня поиск по названию игры. На кой черт мне вообще это число? :D Ввести доп.переменную числового типа и пометить её как primary key? Я попробую, но выглядит абсурдно
вообще-то это первое дело в таблицах иметь поде id primary key
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974299
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вадя
miroooha
А нафига мне числовой то? Если у меня поиск по названию игры. На кой черт мне вообще это число? :D Ввести доп.переменную числового типа и пометить её как primary key? Я попробую, но выглядит абсурдно
вообще-то это первое дело в таблицах иметь поде id primary key

Оно обязательно должно быть числом? У меня есть primary key, который весит на стринге. Мне предлагают снять этот primary key с этой стринги, ввести доп.поле числового типа и повесить на него pk.

Ну я буду пробовать, потом отпишусь о результатах.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974375
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha
Оно обязательно должно быть числом?
если ты хочешь иметь тормоза - то можешь что угодно использовать.
кроме этого поле primary key делают автоинкриментным
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974379
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha,
Долго пробуешь.
Заработает, поставишь строковое. Делов то.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974390
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обычно title не выбирают на роль уникального ключа. По смыслу - он больше атрибут. Или комментарий.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974562
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вадя
miroooha
Оно обязательно должно быть числом?
если ты хочешь иметь тормоза - то можешь что угодно использовать.
кроме этого поле primary key делают автоинкриментным

Ну это понятно, что сравнить два числа гораздо быстрее, чем строку.

Попробовал так:
Вручную ввел доп.поле типа ObjectId, которое генерит сама монго, если не видит аннотации @Id. Повесил на неё @Id, а на название повесил индекс на уникальность. Проверил: взял объект из БД, через сеттер изменил одно из полей и попробовал сохранить измененный объект - всё прошло успешно.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
import org.bson.types.ObjectId;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;

...

@Id
ObjectId id;
@Indexed(unique = true)
String title;



Окей, объект изменился, никаких дубликат error.

Однако, дальше через свой парсер снова пытаюсь сохранить объект (у которого это измененное поле уже другое) - и снова ничего не работает! Чудеса да и только.

Если брать объект из БД, менять через сеттер ему поле, и сохранять обратно - то всё работает. А как только пытаюсь сохранить готовый объект (у которого новое значение в поле) - так снова DuplicateKey.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974563
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha,
Второй нерабочий случай не понял.
Транзакция должна быть короткой 0,1сек.
С коммитом.
Поле id менять нельзя.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974568
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PetroNotC Sharp
miroooha,
Второй нерабочий случай не понял.
Транзакция должна быть короткой 0,1сек.
С коммитом.
Поле id менять нельзя.

Ну в первом случае я взял объект с игрой из БД, сохранил его в локальную переменную, через сеттер изменил значение одного поля и тут же через метод save() сохранил в БД. В результате у этого объекта в БД изменилось соответствующее поле - т.е. то, чего я и добивался.

Про второй случай. У меня же есть парсер, который по ссылке достаёт всю информацию об игре, которую я потом сохраняю в БД. Я знаю, что у меня в БД сейчас лежит объект, у которого тот же самый title, что и у игры, которую я парсю. Но одно поле у объекта, который лежит в БД и объекта, который я получил в ходе парсинга - разные.
Т.е. по идее всё должно сработать как и в первом сценарии - перезаписаться одно поле. Но здесь получаю DuplicateKey.

P.S. Т.е. если я в будущем захочу обновить игру в БД по одной ссылке и 1 запросу с парсера, если у неё условно сменится номер, или цена, то я получу ошибку.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974572
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Грубо говоря, он не хочет просто взять и "переписать" старый объект на новый, у которого новые значения. Надо взять уже имеющийся объект и БД, изменить ему поля и закинуть его обратно. Не очень удобно для моего сценария.

Особенности NoSQL? Mongo? Или моих кривых рук? С Postgres всё работало по описанному сценарию.

Я уже понимаю, что похоже загвоздка в id, так как при парсинге создаётся новый объект. Он видит, что у объектов разные id, но одинаковые поля title и не пускает. Но как её решить..
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974582
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
При каждом запросе залезать в БД и проверять, есть ли там такая игра. Если есть, то достать и сравнить с той, что выдал парсер. Прогнать и сравнить через equals, и в случае несовпадения заменить через сеттер соответствующие поля и обновить объект в БД. Как-то не комильфо.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974597
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miroooha
При каждом запросе залезать в БД и проверять, есть ли там такая игра. Если есть, то достать и сравнить с той, что выдал парсер. Прогнать и сравнить через equals, и в случае несовпадения заменить через сеттер соответствующие поля и обновить объект в БД. Как-то не комильфо.

Ещё один костыль, который только что испробовал: при попытке сохранить объект в БД ловить этот exception на дубликат. В catch блоке во временную переменную складывать объект из БД с таким же названием. Доставать у него этот уникальный id, и через сеттер ставить тому объекту, который пытаюсь сохранить. В результате объект в БД обновляется. Но как-то мне не очень нравится такой вариант (но хоть работает) :D
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974606
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотреть, чем "объект из БД" отличается от того, что ты пытаешься пихать, не судьба?
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974610
miroooha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid Kudryavtsev
Посмотреть, чем "объект из БД" отличается от того, что ты пытаешься пихать, не судьба?

Я это только что выше в принципе и описал.
Просто завернул в catch, чтобы проверять что там нового только в том случае, если такой объект уже есть (при DuplicateKeyExсeption). Проверять каждый нет необходимости.

Просто при работе с Postgres таких проблем не было, он сам всё решал за меня. А здесь вот так вот выходит.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974633
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha
При каждом запросе залезать в БД и проверять, есть ли там такая игра. Если есть, то достать и сравнить с той, что выдал парсер. Прогнать и сравнить через equals, и в случае несовпадения заменить через сеттер соответствующие поля и обновить объект в БД. Как-то не комильфо.

Вы много думаете.
При ОРМ не надо жалеть комп и много думать.
Именно так!
Читаем ПОСЛЕДНЮЮ версию объекта и меняем за 0, 00001 сек.
...
Рейтинг: 0 / 0
Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
    #39974635
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miroooha,
Я не понял что за парсер такой?
Все работы с бд должны быть через одни ворота. Например hibernate.
Если jdbc, то аккуратно и отдельный проект.
Что за парсер?
...
Рейтинг: 0 / 0
25 сообщений из 78, страница 1 из 4
Форумы / Java [игнор отключен] [закрыт для гостей] / Поле объекта в качестве уникального ключа в документе MongoDB (Spring Data)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]