Text Search
Tot nu toe hebben we enkel gezien hoe we exacte waarden kunnen gebruiken om te filteren. MongoDB heeft ook een text search functionaliteit die je kan gebruiken om tekstuele velden te doorzoeken. Dit kan je gebruiken om bijvoorbeeld een zoekfunctionaliteit te maken.
Stel dat we een collectie hebben met de naam books
en we willen alle boeken vinden waarvan de titel het woord "MongoDB" bevat.
interface Book {
_id: ObjectId;
title: string;
summary: string;
}
en
const collection : Collection<Book> = client.db("library").collection<Book>("books");
Deze collection bevat de volgende boeken:
const books: Book[] = [
{ title: "The Great Gatsby", summary: "A book about a rich guy" },
{ title: "MongoDB for Dummies", summary: "A book about a database" },
{ title: "The Catcher in the Rye", summary: "A book about a kid" },
{ title: "The Da Vinci Code", summary: "A book about a code" },
{ title: "The Hobbit", summary: "A book about a hobbit" },
{ title: "Star Wars: The novel", summary: "A book about a galaxy far far away" },
{ title: "Lief klein konijn", summary: "Een boek over een konijntje" }
]
Reguliere expressies
Je kan reguliere expressies gebruiken om tekstuele velden te doorzoeken. Je kan een reguliere expressie meegeven aan de find
methode om te filteren op een bepaald patroon.
const result = await collection.find({ title: /MongoDB/ }).toArray();
Dit geeft alle documenten terug waarvan het veld title
het woord "MongoDB" bevat.
Als je een case-insensitive zoekopdracht wil uitvoeren, dan kan je de i
vlag toevoegen aan de reguliere expressie.
const result = await collection.find({ title: /mongodb/i }).toArray();
Dit geeft alle documenten terug waarvan het veld title
het woord "MongoDB" bevat, ongeacht de case.
Wil je nu zoeken op een bepaalde variabelen, dan kan je de reguliere expressie dynamisch maken.
const search : string = "MongoDB";
const result : Book[] = await collection.find<Book>({ title: new RegExp(search, "i") }).toArray();
Text search
Index aanmaken
Je kan ook een text index aanmaken op een veld om te zoeken op tekst. Je kan een text index aanmaken door de createIndex
methode aan te roepen met als argument een object met als key het veld dat je wil indexeren en als value "text"
.
await collection.createIndex({ title: "text" });
Dit zal een text index aanmaken op het veld title
. Je kan nu de $text
operator gebruiken om te zoeken op tekst.
Zoeken op een woord
const result = await collection.find({ $text: { $search: "MongoDB" } }).toArray();
Over het algemeen is het aanmaken van een text index en text search efficiënter dan het gebruik van reguliere expressies.
Zoeken op meerdere woorden
const result = await collection.find({ $text: { $search: "MongoDB database" } }).toArray();
Dit geeft alle documenten terug waarvan het veld title
de woorden "MongoDB" en "database" bevat.
Enkelvoud en meervoud
Text search is zelfs zo krachtig dat het het onderscheid kan maken tussen enkelvoud en meervoud.
const result = await collection.find({ $text: { $search: "dummy" } }).toArray();
zal ook het boek "MongoDB for Dummies" teruggeven want het bevat het woord "dummy" in het meervoud.
Stopwoorden
Text search houdt ook rekening met stopwoorden. Dit zijn woorden die vaak voorkomen en geen betekenis hebben. Deze worden genegeerd in de zoekopdracht.
const result = await collection.find({ $text: { $search: "the" } }).toArray();
Dit geeft geen resultaten terug omdat "the" een stopwoord is.
Zoeken op meerdere velden
Als je wil zoeken op meerdere velden, dan kan je een text index aanmaken op meerdere velden.
await collection.createIndex({ title: "text", summary: "text" });
De kans bestaat dat je een foutmelding krijgt omdat er al een index bestaat op het title veld. Je kan dit oplossen door eerst de index te verwijderen.
await collection.dropIndex("*")
Dit zal alle indexen verwijderen.
Je kan nu zoeken op meerdere velden.
const result = await collection.find({ $text: { $search: "database" } }).toArray();
Dit geeft alle documenten terug waarvan het veld title
of summary
het woord "database" bevat.
Language optie
Je kan ook de $language
optie meegeven aan de $text
operator om de taal van de tekst te specificeren.
const result = await collection.find({ $text: { $search: "konijnen", $language: "nl" } }).toArray();
Dit geeft alle documenten terug waarvan het veld title
of summary
het woord "konijnen" bevat in het Nederlands. En ja, het boek "Lief klein konijn" zal teruggegeven worden.
Wil je volledig taal onafhankelijk zoeken dan moet je de index aanmaken met de default_language
optie en deze op none
zetten.
await collection.createIndex({ title: "text", summary: "text" }, { default_language: "none" });
Dit is ook handig als je meerdere talen in je collectie hebt en je geen rekening wil houden met stopwoorden en dergelijke.
Last updated