Eine einfache Tagging-Implementierung mit MongoDB

Eine einfache Tagging-Implementierung mit MongoDB

1. Überblick

In diesem Tutorial sehen wir uns eine einfache Tagging-Implementierung mit Java und MongoDB an.

Für diejenigen, die mit dem Konzept nicht vertraut sind,a tag is a keyword used as a “label” to group documents into different categories. Dies ermöglicht es den Benutzern, schnell durch ähnliche Inhalte zu navigieren, und es ist besonders nützlich, wenn Sie mit einer großen Datenmenge arbeiten.

Es ist jedoch nicht verwunderlich, dass diese Technik in Blogs sehr häufig verwendet wird. In diesem Szenario verfügt jeder Beitrag über ein oder mehrere Tags, die den behandelten Themen entsprechen. Wenn der Benutzer mit dem Lesen fertig ist, kann er einem der Tags folgen, um weitere Inhalte zu diesem Thema anzuzeigen.

Mal sehen, wie wir dieses Szenario implementieren können.

2. Abhängigkeit

Um die Datenbank abzufragen, müssen wir die MongoDB-Treiberabhängigkeit in unserepom.xml aufnehmen:


    org.mongodb
    mongo-java-driver
    3.6.3

Die aktuelle Version dieser Abhängigkeit finden Sie inhere.

3. Datenmodell

Lassen Sie uns zunächst planen, wie ein Post-Dokument aussehen soll.

Zur Vereinfachung enthält unser Datenmodell nur einen Titel, den wir auch als Dokument-ID, einen Autor und einige Tags verwenden.

Wir werden die Tags in einem Array speichern, da ein Beitrag wahrscheinlich mehr als nur eines enthält:

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

Wir erstellen auch die entsprechende Java-Modellklasse:

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

    // getters and setters
}

4. Tags aktualisieren

Nachdem wir die Datenbank eingerichtet und einige Beispielbeiträge eingefügt haben, wollen wir sehen, wie wir sie aktualisieren können.

Our repository class will include two methods to handle the addition and removal of tags, indem Sie den Titel verwenden, um sie zu finden. Wir geben auch einen Booleschen Wert zurück, um anzugeben, ob die Abfrage ein Element aktualisiert hat oder nicht:

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

Wir haben die MethodeaddEachToSet anstelle vonpush für die Hinzufügung verwendet, sodass wir die Tags nicht erneut hinzufügen, wenn sie bereits vorhanden sind.

Beachten Sie auch, dass der OperatoraddToSetauch nicht funktioniert, da er die neuen Tags als verschachteltes Array hinzufügt, was nicht das ist, was wir wollen.

Another way we can perform our updates is through the Mongo shell. Zum Beispiel aktualisieren wir den BeitragJUnit5 with Java.. Insbesondere möchten wir die TagsJava und JUnit5 hinzufügen und die TagsSpring undREST:

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

Lassen Sie uns zu guter Letzt einige der häufigsten Fragen durchgehen, die uns bei der Arbeit mit Tags interessieren könnten. Zu diesem Zweck nutzen wir insbesondere drei Array-Operatoren:

  • $in – gibt die Dokumente zurück, in denena field contains any value des angegebenen Arrays enthalten sind

  • $nin – gibt die Dokumente zurück, in denena field doesn’t contain any value des angegebenen Arrays enthalten sind

  • $all – gibt die Dokumente zurück, in denena field contains all the values des angegebenen Arrays enthalten sind

We’ll define three methods to query the posts in relation to a collection of tags passed as arguments. Sie geben die Posts zurück, die mindestens einem Tag, allen Tags und keinem der Tags entsprechen. Außerdem erstellen wir eine Zuordnungsmethode für die Konvertierung zwischen einem Dokument und unserem Modell mithilfe der Stream-API von 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;
}

Wiederumlet’s also take a look at the shell equivalent queries. Wir werden drei verschiedene Postsammlungen abrufen, die jeweils mitMongoDB oderStream API gekennzeichnet sind, sowohl mitJava 8 als auch mitJUnit 5 und nicht mitGroovy oderScala:

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

In diesem Artikel wurde gezeigt, wie ein Tagging-Mechanismus erstellt wird. Natürlich können wir diese Methode auch für andere Zwecke als für einen Blog verwenden und erneut anpassen.

Wenn Sie weiter daran interessiert sind, MongoDB zu lernen,we encourage you to read this introductory article.

Wie immer ist der gesamte Code im Beispielover on the Github project verfügbar.