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

Простая реализация тегов с MongoDB

Узнайте, как реализовать механизм пометки с помощью MongoDB.

Автор оригинала: Donato Rimenti.

1. Обзор

В этом учебнике мы посмотрим на простую реализацию тегов с помощью Java и MongoDB.

Для тех, кто не знаком с концепцией, тег — это ключевое слово, используемое в качестве «метки» для группы документов по разным категориям. Это позволяет пользователям быстро перемещаться по аналогичному контенту, и это особенно полезно при работе с большим объемом данных.

Это, как говорится, это не удивительно, что этот метод очень часто используется в блогах. В этом сценарии каждая должность имеет один или несколько тегов в соответствии с рассматриваемыми темами. Когда пользователь заканчивает чтение, он может следовать одному из тегов, чтобы просмотреть больше контента, связанного с этой темой.

Давайте посмотрим, как мы можем реализовать этот сценарий.

2. Зависимость

Для запроса базы данных нам придется включить зависимость драйвера MongoDB в наш пом.xml :


    org.mongodb
    mongo-java-driver
    3.6.3

Текущую версию этой зависимости можно найти здесь .

3. Модель данных

Прежде всего, давайте начнем с планирования того, что почтовый документ должен выглядеть.

Чтобы все было просто, наша модель данных будет иметь только название, которое мы также будем использовать в качестве идентификатора документа, автора и некоторых тегов.

Мы будем хранить теги внутри массива, так как сообщение, вероятно, будет иметь больше, чем просто один:

{
    "_id" : "Java 8 and MongoDB",
    "author" : "Donato Rimenti",
    "tags" : ["Java", "MongoDB", "Java 8", "Stream API"]
}

Мы также создадим соответствующий класс Java-модели:

public class Post {
    private String title;
    private String author;
    private List tags;

    // getters and setters
}

4. Обновление тегов

Теперь, когда мы создали базу данных и вставили несколько примеров сообщений, давайте посмотрим, как мы можем обновить их.

Наш класс репозитория будет включать в себя два метода обработки добавления и удаления тегов с помощью названия, чтобы найти их. Мы также вернем boolean, чтобы указать, обновил ли запрос элемент или нет:

public boolean addTags(String title, List tags) {
    UpdateResult result = collection.updateOne(
      new BasicDBObject(DBCollection.ID_FIELD_NAME, title), 
      Updates.addEachToSet(TAGS_FIELD, tags));
    return result.getModifiedCount() == 1;
}

public boolean removeTags(String title, List tags) {
    UpdateResult result = collection.updateOne(
      new BasicDBObject(DBCollection.ID_FIELD_NAME, title), 
      Updates.pullAll(TAGS_FIELD, tags));
    return result.getModifiedCount() == 1;
}

Мы использовали addEachToSet метод вместо толкать для добавления, так что если теги уже есть, мы не будем добавлять их снова.

Обратите внимание также, что добавитьToSet Оператор не будет работать либо, поскольку он будет добавлять новые теги, как вложенный массив, который не то, что мы хотим.

Еще один способ, мы можем выполнять наши обновления через оболочку Mongo. Например, давайте обновим пост JUnit5 с Java. В частности, мы хотим добавить теги Java и J Unit5 и удалить теги Весенние и REST :

db.posts.updateOne(
    { _id : "JUnit 5 with Java" }, 
    { $addToSet : 
        { "tags" : 
            { $each : ["Java", "JUnit5"] }
        }
});

db.posts.updateOne(
    {_id : "JUnit 5 with Java" },
    { $pull : 
        { "tags" : { $in : ["Spring", "REST"] }
    }
});

5. Запросы

И последнее, но не менее важное, давайте рассмотрим некоторые из наиболее распространенных запросов, которые могут нас заинтересовать во время работы с тегами. Для этого мы воспользуемся тремя операторами массивов, в частности:

  • $in – возвращает документы там, поле содержит любое значение указанного массива
  • $nin – возвращает документы там, поле не содержит значения указанного массива
  • $all – возвращает документы там, поле содержит все значения указанного массива

public List postsWithAtLeastOneTag(String... tags) {
    FindIterable results = collection
      .find(Filters.in(TAGS_FIELD, tags));
    return StreamSupport.stream(results.spliterator(), false)
      .map(TagRepository::documentToPost)
      .collect(Collectors.toList());
}

public List postsWithAllTags(String... tags) {
    FindIterable results = collection
      .find(Filters.all(TAGS_FIELD, tags));
    return StreamSupport.stream(results.spliterator(), false)
      .map(TagRepository::documentToPost)
      .collect(Collectors.toList());
}

public List postsWithoutTags(String... tags) {
    FindIterable results = collection
      .find(Filters.nin(TAGS_FIELD, tags));
    return StreamSupport.stream(results.spliterator(), false)
      .map(TagRepository::documentToPost)
      .collect(Collectors.toList());
}

private static Post documentToPost(Document document) {
    Post post = new Post();
    post.setTitle(document.getString(DBCollection.ID_FIELD_NAME));
    post.setAuthor(document.getString("author"));
    post.setTags((List) document.get(TAGS_FIELD));
    return post;
}

Опять же, давайте также рассмотрим эквивалентные оболочки запросы . Мы будем получать три различных пост коллекции соответственно помечены МонгоДБ или Поток API, помеченный обоими Java 8 и JUnit 5 и не помечены Груви ни Скала :

db.posts.find({
    "tags" : { $in : ["MongoDB", "Stream API" ] } 
});

db.posts.find({
    "tags" : { $all : ["Java 8", "JUnit 5" ] } 
});

db.posts.find({
    "tags" : { $nin : ["Groovy", "Scala" ] } 
});

6. Заключение

В этой статье мы показали, как создать механизм пометки. Конечно, мы можем использовать и readapt эту же методологию для других целей, кроме блога.

Если вы заинтересованы в дальнейшем изучении MongoDB, мы рекомендуем вам прочитать эту вступительную статью .

Как всегда, весь код в примере доступен более на Github проекта .

« предыдущий Расширенная реализация тегов с JPA