mongo Query - Lesbare, einfache MongoDB Abfragen in Go

mongo Query - Lesbare, einfache MongoDB Abfragen in Go

Abfragen für eine MongoDB zu formulieren macht keinen wirklichen Spaß. Über verschachtelte BSON-Strukturen müssen die Daten in der Datenbank abgefragt werden. MongoDB sagt zwar selbst: “Die Abfrage-API. Eine natürliche Art, mit Daten zu arbeiten.“, aber so ganz natürlich hat es sich für uns nicht angefühlt.

In diversen Projekten hatten wir das Gefühlt MongoDB Zugriffscode zu produzieren, der schwer lesbar und dadurch auch schwer wartbar ist. Jetzt könnte man an dieser Stelle sagen: “Ok, ist ja nur an der einen Stelle,….“, aber genau das wollten wir nicht.

mongo Query

Wir haben begonnen eine Abfragemöglichkeit, ähnlich zur Java-basierten Lösung QueryDSL, zu bauen, mit der man Daten aus einer MongoDB über eine statische API abfragen kann. Sie unterstützt aktuell die meisten Operatoren der MongoDB API und die Abfrageobjekte können von einem kleinen Generator aus den BSON-Mappings erstellt werden.

Das ganze haben wir dann noch etwas angepasst und in eine Golang Open Source Bibliothek gepackt: https://github.com/SourceFellows/mongo-query

mongo Query Logo

mongo Query

Folgende Abfrage liefert zum Beispiel alle Dokumente bei denen 15 Elemente in ‘Amenities’ gespeichert sind und die ListingUrl <value> enthält, sowie das verschachtelte Feld PictureUrl ebenfalls den Wert <value> besitzt:

Listing.Amenities.ArraySize(15).
  And(Listing.ListingUrl.Equals("<value>"),
      Listing.Images.PictureUrl.Equals("<value>"))

Der Ausdruck ist:

  • Lesbar
  • Ausdrucksstark
  • Einfach zu Schreiben
  • benötigt kein Aufbau einer bson.D oder bson.M Struktur
  • Unabhängig vom Mapping der BSON-Struktur

Vergleich MongoDB API vs mongo Query

Wenn man die Abfragen über die reine MongoDB API der mongo Query API gegenüberstellt, sieht man recht gut, dass die Abfragen mittels mongo Query einfacher zu lesen und dadurch auch zu warten sind. Auch Änderungen am BSON-Mapping schlagen hier nicht so stark zu Buche, da dies nicht mehr in jeder Abfrage, sondern an einer zentralen Stelle, in den Filter-Objekten, stattfindet.

//MongoDB API
err = findWithFilter(ctx, collection, bson.D{{"size.uom", "in"}})
//mongo Query
err = findWithFilter(ctx, collection, InventoryFilter.Size.Uom.Equals("in"))

Wie man mongo query einsetzt

Ausgangsbasis für den Einsatz der ‘mongo Query’ Bibliothek ist ein Struct, das die Datenstruktur der Dokumente in einer Datenbank wiederspiegelt und für das ein BSON-Mapping vorhanden ist.

Zum Beispiel folgendes Struct:

type ListingAndReview struct {
	Id                   string               `bson:"_id"`
	ListingUrl           string               `bson:"listing_url"`
	Name                 string               `bson:"name"`
	Amenities            []string             `bson:"amenities"`
	Images               struct {
		ThumbnailUrl string `bson:"thumbnail_url"`
		MediumUrl    string `bson:"medium_url"`
		PictureUrl   string `bson:"picture_url"`
		XlPictureUrl string `bson:"xl_picture_url"`
	} `bson:"images"`
}

Mit Hilfe des Command-Line Generators kann man im Anschluss ein entsprechendes Filterobjekt generieren. Zuerst muss dieser allerdings installiert werden.

Installation Command-Line Generator

Die Installation des Generators erfolgt, wie meist, über einen einfachen go install Aufruf:

go install github.com/sourcefellows/mongo-query/cmd/mongo-query-gen@latest

Generierung der Filterobjekte

Mit folgendem Kommando können die entsprechenden Filterobjekte erstellt werden. Im Beispiel muss sich das Struct von oben in der Daten Types.go befinden.

mongo-query-gen -in Types.go -outDir .

Abfrage der Daten aus MongoDB

Jetzt fehlt nur noch die Abfrage. Die generierten Filter-Objekte können direkt als BSON-Filter genutzt werden, so dass kein zusätzlicher, spezieller Call nötig ist.

filter := Listing.ListingUrl.Equals("https://www.airbnb.com/rooms/10009999")
collection := client.Database("airbnb").Collection("listingsAndReviews")
cursor, err := collection.Find(ctx, filter)

mongo Query unterstützt bereits die meisten Query Optionen der MongoDB API. Einfach ausprobieren!

Feedback

Wir sind offen für weitere Anwendungsfälle und Feedback! Viel Spaß mit der Bibliothek.

12.01.2024

 

Der Author auf LinkedIn: Kristian Köhler und Mastodon: @kkoehler@mastodontech.de

Kennen Sie schon das Buch zum Thema?

Der praktische Soforteinstieg für Developer und Softwarearchitekten, die direkt mit Go produktiv werden wollen.

  • Von den Sprachgrundlagen bis zur Qualitätssicherung
  • Architekturstil verstehen und direkt anwenden
  • Idiomatic Go, gRPC, Go Cloud Development Kit
  • Cloud-native Anwendungen erstellen
Microservices mit Go Buch

zur Buchseite beim Rheinwerk Verlag Rheinwerk Computing, ISBN 978-3-8362-7559-0 (als PDF, EPUB, MOBI und Papier)

Kontakt

Source Fellows GmbH

Source Fellows GmbH Logo

Lerchenstraße 31

72762 Reutlingen

Telefon: (0049) 07121 6969 802

E-Mail: info@source-fellows.com