Une simple implémentation de marquage avec MongoDB

Une mise en œuvre simple de marquage avec MongoDB

1. Vue d'ensemble

Dans ce didacticiel, nous allons examiner une implémentation de balisage simple à l'aide de Java et MongoDB.

Pour ceux qui ne connaissent pas le concept,a tag is a keyword used as a “label” to group documents into different categories. Cela permet aux utilisateurs de naviguer rapidement dans un contenu similaire et c'est particulièrement utile lorsqu'il s'agit de traiter une grande quantité de données.

Cela dit, il n’est pas surprenant que cette technique soit très couramment utilisée dans les blogs. Dans ce scénario, chaque publication comporte une ou plusieurs balises en fonction des sujets abordés. Lorsque l'utilisateur a fini de lire, il peut suivre l'une des balises pour afficher plus de contenu lié à ce sujet.

Voyons comment nous pouvons mettre en œuvre ce scénario.

2. Dépendance

Pour interroger la base de données, nous devrons inclure la dépendance du pilote MongoDB dans nospom.xml:


    org.mongodb
    mongo-java-driver
    3.6.3

La version actuelle de cette dépendance peut être trouvéehere.

3. Modèle de données

Tout d'abord, commençons par planifier à quoi doit ressembler un document de publication.

Pour faire simple, notre modèle de données n'aura qu'un titre, que nous utiliserons également comme identifiant du document, un auteur et des balises.

Nous stockerons les balises dans un tableau, car un article en contiendra probablement plusieurs:

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

Nous allons également créer la classe de modèle Java correspondante:

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

    // getters and setters
}

4. Mise à jour des balises

Maintenant que nous avons configuré la base de données et inséré quelques exemples de messages, voyons comment nous pouvons les mettre à jour.

Our repository class will include two methods to handle the addition and removal of tags en utilisant le titre pour les trouver. Nous renverrons également un booléen pour indiquer si la requête a mis à jour un élément ou non:

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;
}

Nous avons utilisé la méthodeaddEachToSet au lieu depush pour l'ajout de sorte que si les balises sont déjà là, nous ne les ajoutons plus.

Notez également que l'opérateuraddToSet ne fonctionnerait pas non plus car il ajouterait les nouvelles balises sous forme de tableau imbriqué, ce qui n'est pas ce que nous voulons.

Another way we can perform our updates is through the Mongo shell. Par exemple, mettons à jour le postJUnit5 with Java. En particulier, nous voulons ajouter les balisesJava et JUnit5 et supprimer les balisesSpring etREST:

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. Des requêtes

Enfin, passons en revue certaines des requêtes les plus courantes susceptibles de nous intéresser lorsque vous travaillez avec des tags. Pour cela, nous allons tirer parti de trois opérateurs de tableau en particulier:

  • $in – renvoie les documents oùa field contains any value du tableau spécifié

  • $nin – renvoie les documents oùa field doesn’t contain any value du tableau spécifié

  • $all – renvoie les documents oùa field contains all the values du tableau spécifié

We’ll define three methods to query the posts in relation to a collection of tags passed as arguments. Ils renverront les messages qui correspondent à au moins une balise, toutes les balises et aucune des balises. Nous allons également créer une méthode de mappage pour gérer la conversion entre un document et notre modèle à l'aide de l'API Stream de Java 8:

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;
}

Encore une fois,let’s also take a look at the shell equivalent queries. Nous allons récupérer trois collections de publications différentes respectivement marquées avec l'APIMongoDB ouStream, marquées à la fois avecJava 8 etJUnit 5 et non marquées avecGroovy niScala:

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. Conclusion

Dans cet article, nous avons montré comment créer un mécanisme de marquage. Bien sûr, nous pouvons utiliser et réadapter cette même méthodologie à d’autres fins que celle d’un blog.

Si vous souhaitez en savoir plus sur MongoDB,we encourage you to read this introductory article.

Comme toujours, tout le code de l'exemple est disponibleover on the Github project.