Рубрики
Без рубрики

Проверьте наличие уникальных документов в MongoDB с помощью Spring Boot

Выясняя, как работают исключения, я хотел убедиться, что сообщения в блоге всегда уникальны…. С тегами codenewbie, mongodb, java, обучение.

Выясняя, как работают исключения, я хотел убедиться, что сообщения в блоге всегда уникальны. Но как нам это сделать? Вот почему я покажу вам, как проверять наличие уникальных документов в MongoDB с помощью Spring Boot.

@Индексированная аннотация

Сначала я заглянул в аннотацию @Indexed из Spring Boot. Эта аннотация создаст новый индекс в MongoDB. Вы можете добавить дополнительные параметры в аннотацию, чтобы она делала что-то более конкретное для вас. В моем случае я использую параметр unique , чтобы позволить MongoDB проверить, является ли определенное поле уникальным. При этом мой класс записей в блоге выглядит так.

@Document(collection = "blogposts")
public class BlogPost {

    @Id
    private String documentId;
    @Indexed(unique = true)
    private String endPoint;
    @JsonFormat(pattern="dd-MM-yyyy HH:mm")
    private Date publishDate;
    private List categories;
    private List tags;
    private String article;

Когда я тестирую эту конфигурацию, ничего не происходит. Я все еще могу добавлять сообщения в блог с повторяющимися конечными точками. Позже я столкнулся с этим сообщением в StackOverflow, в котором говорится, что я должен добавить строку spring.data.mongodb.автоматическое создание индекса=true в мое приложение.свойства . Итак, я добавил строку, даже полностью удалил базу данных и перезапустил MongoDB, но безрезультатно.

Запрос уникальных документов

После пары часов споров с аннотацией @Indexed я, наконец, сдаюсь. Тем не менее, я хочу найти способ проверить наличие уникальных документов в MongoDB с помощью Spring Boot. Поэтому я прибегаю к другому способу достижения этой цели: с помощью запроса к базе данных. Возможно, это не самый быстрый способ, но пока его будет достаточно.

В идеале, то, что я хочу, чтобы запрос выполнял, – это сообщить мне, есть ли в моей базе данных уже сообщение в блоге с тем же значением для конечной точки . Я начинаю работать над документацией Spring Data для MongoDB , пытаясь понять, как настроить мой запрос. После еще одного поиска я нахожу документацию MongoDB на $существует . В одном из их примеров используется $существует в сочетании с $ нин для сбора документов, в которых поле существует и его значение не равно заданному вами значению.

$существует и $nin

Блестяще! Давайте попробуем это сделать. Во-первых, я начинаю с создания логического значения для хранения моего результата со следующим фрагментом кода. Затем я использую логическое значение в своем операторе if, чтобы решить, сохранять объект или нет.

@Override
public void createBlogPost(BlogPost blogPost) {
    boolean postExistsAlready = mongoTemplate.query(BlogPost.class)
        .matching(Query.query(where("endPoint").exists(true).nin(blogPost.getEndPoint()))).exists();

    if(!postExistsAlready) {
        mongoTemplate.save(blogPost, "blogposts");
        System.out.println("Posted!!!");
    }
    else {
        System.out.println("Post already exists!!!");
    }
}

Я снова проверяю, и, конечно же, это не сработало. Без каких-либо ошибок, появляющихся в моей консоли, я прибегнул к PowerShell и сразу перешел в MongoDB. После входа в систему я проверяю, какие данные уже присутствуют в моей коллекции баз данных, используя db.сообщения в блоге.найти() . Затем я пробую версию своего запроса MongoDB со следующей строкой: db.blogpost.find(конечная точка:{$существует: истина, $девять: "/тест"}}) . Возможно, было немного поздно, когда я работал над этим, потому что здесь явно опечатка. Тем не менее, я выяснил одну причину, по которой ничего не происходило, потому что при попытке выполнить запрос я получил ошибку.

По-видимому, $ для nin требуется массив в качестве входных данных, а не просто строка. К счастью, это довольно легко исправить! С небольшой корректировкой кода теперь это выглядит так.

@Override
public void createBlogPost(BlogPost blogPost) {
    String[] endPoint = new String[] {blogPost.getEndpoint()};

    boolean postExistsAlready = mongoTemplate.query(BlogPost.class)
        matching(Query.query(where("endPoint").exists(true).nin(endPoint))).exists();

    if(!postExistsAlready) {
        mongoTemplate.save(blogPost, "blogposts");
        System.out.println("Posted!!!");
    else {
        System.out.println("Post already exists!!!");
    }
}

Классно! Давай попробуем еще раз. Тоже не повезло.

$существует и $в

На этом этапе я начинаю задаваться вопросом, правильно ли я использую методы запроса, особенно учитывая, что впереди будет еще много сообщений в блоге. По какому-то наитию я повозился в монго с PowerShell. Вместо использования $nin , я попробовал с помощью метода подсчета. Итак, я попробовал следующий запрос в своем PowerShell: db.blogposts.count({"Конечная точка":{$существует: истина, $в:["/тест"]}}) .

Ну, ты только посмотри на это! Когда я использую $nin , мой счетчик возвращает 0, потому что в моей базе данных нет документов, в которых нет /теста как их конечная точка. Однако, когда я использую , запрос возвращает мне количество статей, которые делать иметь /тест как их конечная точка. Это именно то, что мне нужно!

Итак, я снова скорректировал свой код, чтобы использовать эту информацию. Окончательная версия на данный момент выглядит так.

@Override
public void createBlogPost(BlogPost blogPost) {
    String[] endPoint = new String[] {blogPost.getEndPoint()};

    Query query = new Query();
    query.addCriteria(Criteria.where("endPoint").in(endpoint));

    boolean postExistsAlready = mongoTemplate.exists(query, BlogPost.class);

    if(!postExistsAlready) {
        mongoTemplate.save(blogPost, "blogposts");
        System.out.println("Posted!!!");
    }
    else {
        System.out.println("Post Already Exists!!!");
    }
}

Вывод

Потребовалось немного времени, чтобы разобраться во всем этом, и я еще не закончил с аннотацией @Indexed . Использование такого запроса пока работает, но в конечном счете я думаю, что было бы лучше использовать то, что доступно для нас в MongoDB. Я видел способы добавления индекса вручную, но это требует дополнительных исследований. А пока я счастлив, что разгадал эту маленькую загадку.

Теперь я согласен с тем, что эти System.out.println() утверждения далеки от красивых. Нет никакого способа уведомить пользователя о том, что что-то пошло не так. Итак, следующий шаг – выяснить, как обрабатывать создаваемые исключения!

Оригинал: “https://dev.to/shadowphoenix/check-for-unique-documents-in-mongodb-with-spring-boot-971”