sql >> Databáze >  >> NoSQL >> MongoDB

Jednoduchá implementace značkování s MongoDB

Tento článek je součástí série:• Jednoduchá implementace tagování s Elasticsearch
• Jednoduchá implementace značkování pomocí JPA
• Pokročilá implementace značkování s JPA
• Jednoduchá implementace značkování s MongoDB (aktuální článek)

1. Přehled

V tomto tutoriálu se podíváme na jednoduchou implementaci značkování pomocí Javy a MongoDB.

Pro ty, kteří tento koncept neznají, značka je klíčové slovo používané jako „štítek“ k seskupování dokumentů do různých kategorií. To umožňuje uživatelům rychle procházet podobným obsahem a je to užitečné zejména při práci s velkým množstvím dat.

Jak již bylo řečeno, není divu, že tato technika je v blozích velmi běžně používána. V tomto scénáři má každý příspěvek jeden nebo více štítků podle probíraných témat. Když uživatel dočte, může sledovat jeden ze štítků a zobrazit si další obsah související s daným tématem.

Podívejme se, jak můžeme tento scénář implementovat.

2. Závislí

Abychom mohli dotazovat databázi, budeme muset do pom.xml zahrnout závislost ovladače MongoDB :

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.6.3</version>
</dependency>

Aktuální verzi této závislosti naleznete zde.

3. Datový model

Nejprve začněme plánováním, jak by měl poštovní dokument vypadat.

Aby to nebylo jednoduché, náš datový model bude mít pouze název, který také použijeme jako ID dokumentu, autora a některé značky.

Značky uložíme do pole, protože příspěvek bude mít pravděpodobně více než jen jeden:

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

Vytvoříme také odpovídající třídu modelu Java:

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

    // getters and setters
}

4. Aktualizace značek

Nyní, když jsme nastavili databázi a vložili několik ukázkových příspěvků, pojďme se podívat, jak je můžeme aktualizovat.

Naše třída úložiště bude zahrnovat dvě metody pro přidávání a odstraňování značek pomocí názvu k jejich nalezení. Vrátíme také boolean označující, zda dotaz aktualizoval prvek či nikoli:

public boolean addTags(String title, List<String> 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<String> tags) {
    UpdateResult result = collection.updateOne(
      new BasicDBObject(DBCollection.ID_FIELD_NAME, title), 
      Updates.pullAll(TAGS_FIELD, tags));
    return result.getModifiedCount() == 1;
}

Použili jsme addEachToSet metoda namísto push pro přidání, takže pokud tam již značky jsou, nebudeme je znovu přidávat.

Všimněte si také, že addToSet Nefungoval by ani operátor, protože by přidal nové značky jako vnořené pole, což není to, co chceme.

Další způsob, jak můžeme provádět aktualizace, je prostřednictvím prostředí Mongo. Například aktualizujme příspěvek JUnit5 pomocí Javy. Konkrétně chceme přidat tagy Java a JJednotka5 a odstraňte štítky Jaro a ODPOČINEK :

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

V neposlední řadě si pojďme projít některé z nejčastějších dotazů, které nás mohou při práci se značkami zajímat. Pro tento účel využijeme zejména tří operátorů pole:

  • $in – vrátí dokumenty, kde pole obsahuje jakoukoli hodnotu zadaného pole
  • $nin – vrátí dokumenty, kde pole neobsahuje žádnou hodnotu zadaného pole
  • $all – vrátí dokumenty, kde pole obsahuje všechny hodnoty zadaného pole

Budeme definovat tři způsoby dotazování příspěvků ve vztahu ke sbírce značek předávaných jako argumenty . Vrátí příspěvky, které odpovídají alespoň jednomu štítku, všem štítkům a žádnému štítku. Vytvoříme také metodu mapování pro zpracování převodu mezi dokumentem a naším modelem pomocí rozhraní Stream API Java 8:

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

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

public List<Post> postsWithoutTags(String... tags) {
    FindIterable<Document> 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<String>) document.get(TAGS_FIELD));
    return post;
}

Opět se podívejme také na dotazy ekvivalentní shellu . Načteme tři různé kolekce příspěvků, které jsou označeny MongoDB nebo Stream API, označené oběma Java 8 a Jednotka 5 a neoznačené Groovy ani Scala :

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

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

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

  1. Jak se mohu připojit k MongoDB Atlas pomocí Robomongo?

  2. MongoDB cursor.count()

  3. Jak na to:Testování aplikací HBase pomocí oblíbených nástrojů

  4. Po aktualizaci se změní pořadí pole MongoDB a pozice dokumentu