MongoDB
MongoDB bir doküman veritabanıdır. Temel veri birimi dokümandır ve BSON (Binary JSON) formatında saklanır. BSON, JSON'a benzer bir yapıdır. Esnek yapısı farklı türde verilerin saklanmasına olanak tanır. İlişkisel veritabanlarına kıyasla daha esnektir ve JavaScript betik dili olarak kullanılarak kombinasyon işlemleri betiklerle tamamlanabilir. Bu makale, Go'da resmi mongo sürücüsü kullanılarak mongodb veritabanının nasıl kullanılacağını anlatmaktadır. Bu bir mongodb eğitimi değildir. Eğer mongodb temeliniz yoksa, lütfen önce kendi başınıza öğrenin.
mongodb dokümantasyonu: Introduction to MongoDB — MongoDB Manual
Sürücü
Go tarafındaki kütüphaneler nispeten azdır. Erken dönemde bazı topluluk tarafından sürdürülen kütüphaneler vardı, ancak daha sonra bakımları durduruldu. Ancak resmi mongo sürücü kütüphanesi tamamen yeterlidir.
Açık kaynak depo: mongodb/mongo-go-driver: The Official Golang driver for MongoDB (github.com)
Dokümantasyon adresi: mongodb/mongo-go-driver: The Official Golang driver for MongoDB (github.com)
Kurulum
Bağımlılığı indirmek için aşağıdaki adresi kullanabilirsiniz.
$ go get go.mongodb.org/mongo-driver/mongoBağlantı
Aşağıda mongo istemcisi ile sunucu arasında bağlantı kuran basit bir örnek bulunmaktadır.
package main
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
"log"
)
func main() {
ctx := context.Background()
// URI kullanarak bağlantı kur
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://admin:123456@192.168.48.138:27017/"))
if err != nil {
log.Panicln(err)
}
// Bağlantıyı kapat
defer client.Disconnect(ctx)
// Ping testi ile bağlantının kullanılabilir olup olmadığını kontrol et
fmt.Println(client.Ping(ctx, readpref.Primary()))
}bson
mongodb, Go'da veritabanındaki dokümanları eşleştirmek için aşağıdaki türleri kullanır. Bunlar bson/bson.go dosyasında bulunur:
// BSON dokümanının sıralı gösterimi
type D = primitive.D
// Anahtar-değer çifti, BSON dokümanının sıralı gösteriminin temel birimi
type E = primitive.E
// BSON dokümanının sırasız gösterimi
type M = primitive.M
// BSON verisinin sıralı gösterimi
type A = primitive.AGerçek türleri aşağıdaki gibidir:
// BSON dokümanının sıralı gösterimi
type D []E
// Anahtar-değer çifti, BSON dokümanının sıralı gösteriminin temel birimi
type E struct {
Key string
Value interface{}
}
// BSON dokümanının sırasız gösterimi
type M map[string]interface{}
// BSON verisinin sıralı gösterimi
type A []interface{}Bu türler kullanılarak hem sorgu SQL'leri oluşturulabilir hem de veriler eşleştirilebilir.
TIP
Sürücünün examples dizininde oldukça fazla kullanım örneği bulunmaktadır. Resmi olarak yukarıdaki dört türün nasıl kullanılacağı çok detaylı bir şekilde gösterilmiştir.
Doküman Sorgulama
Resmi sorgu örneği: mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)
Önce user veritabanını oluşturun, users koleksiyonuna aşağıdaki verileri ekleyin:
> use user
> db.users.insertMany([
{
name: "mike",
age: 12,
},
{
name: "jenny",
age: 14,
},
{
name: "jack",
age: 18,
address: "usa"
}
])Tekil Sorgulama
type User struct {
Name string `bson:"name"`
Age int `bson:"age"`
Address string `bson:"address"`
}
var user User
result := client.Database("user"). // Veritabanını seç
Collection("users"). // Koleksiyonu seç
FindOne(ctx, bson.D{{"address", "usa"}}) // Filtre koşulu
// Serileştirme
if err := result.Decode(&user); err != nil {
log.Panicln(err)
}
fmt.Printf("%+v\n", user)Yukarıdaki sorgu kodu şununla eşdeğerdir:
db.users.findOne({
address: "usa"
})Çıktı sonucu
{Name:jack Age:18 Address:usa}Çoklu Sorgulama
type User struct {
Name string `bson:"name"`
Age int `bson:"age"`
Address string `bson:"address"`
}
var users []User
cursor, err := client.Database("user"). // Veritabanını seç
Collection("users"). // Koleksiyonu seç
Find(ctx, bson.D{}) // Filtre koşulu
if err != nil {
log.Panicln(err)
}
if err := cursor.All(ctx, &users); err != nil {
log.Panicln(err)
}
fmt.Printf("%+v\n", users)Şununla eşdeğerdir:
db.users.find({})Çıktı
[{Name:jack Age:18 Address:usa} {Name:mike Age:12 Address:} {Name:jenny Age:14 Address:}]Sorgu koşullarını oluştururken options da kullanılabilir:
type User struct {
Name string `bson:"name"`
Age int `bson:"age"`
Address string `bson:"address"`
}
var users []User
find := options.Find()
find.SetSort(bson.M{"age": 1})
find.SetLimit(1)
cursor, err := client.Database("user"). // Veritabanını seç
Collection("users"). // Koleksiyonu seç
Find(ctx, bson.D{}, find) // Filtre koşulu
if err != nil {
log.Panicln(err)
}
if err := cursor.All(ctx, &users); err != nil {
log.Panicln(err)
}
fmt.Printf("%+v\n", users)Şununla eşdeğerdir:
db.users.find({}).sort({age:1}).limit(1)Çıktı
[{Name:mike Age:12 Address:}]Doküman Oluşturma
Resmi oluşturma örneği: mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)
Aşağıda bir doküman oluşturma örneği bulunmaktadır:
one, err := client.Database("user").Collection("users").InsertOne(ctx, User{
Name: "lili",
Age: 20,
Address: "china",
})
if err != nil {
log.Panicln(err)
}
fmt.Println(one.InsertedID)Oluşturma başarılı olduktan sonra dokümanın ObjectID'si döndürülür:
ObjectID("64c60fa01e2548d9e4de6cf4")Aşağıda birden fazla doküman oluşturma örneği bulunmaktadır:
users := []any{User{
Name: "john",
Age: 10,
Address: "usa",
}, User{
Name: "pop",
Age: 30,
Address: "uk",
}}
one, err := client.Database("user").Collection("users").InsertMany(ctx, users)
if err != nil {
log.Panicln(err)
}
fmt.Println(one.InsertedIDs)Oluşturma başarılı olduktan sonra bir grup ObjectID döndürülür:
[ObjectID("64c610d5aec2618d6ca0b515") ObjectID("64c610d5aec2618d6ca0b516")]Yukarıdaki iki kod parçası sırasıyla db.users.insertOne ve db.users.insertMany ile eşdeğerdir.
Doküman Güncelleme
Resmi güncelleme örneği: mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)
Aşağıda tek bir dokümanı güncelleme örneği bulunmaktadır. lili adlı kişiyi mark olarak değiştirin:
upres, err := client.Database("user").Collection("users").UpdateOne(ctx, bson.D{
{"name", "mark"},
},
bson.D{
{"$set", bson.D{
{"name", "lili"},
}},
})
if err != nil {
log.Panicln(err)
}
fmt.Printf("%+v", upres)Şununla eşdeğerdir:
db.users.updateOne({
name: "lili"
}, {
$set: {
name: "mark"
},
})Çıktı
&{MatchedCount:1 ModifiedCount:1 UpsertedCount:0 UpsertedID:<nil>}Aşağıda birden fazla dokümanı güncelleme örneği bulunmaktadır. Yaşı 10 olan kişilerin adresini cn olarak güncelleyin:
upres, err := client.Database("user").Collection("users").UpdateMany(ctx, bson.D{
{"age", 10},
},
bson.D{
{"$set", bson.D{
{"address", "cn"},
}},
})
if err != nil {
log.Panicln(err)
}
fmt.Printf("%+v", upres)Update kullanımının yanı sıra, mongo Replace da sağlar. İkisi arasındaki fark, birincisi doküman alanlarını günceller, ikincisi ise dokümanı doğrudan değiştirir. Örneğin aşağıdaki kodda artık operatörlere ihtiyaç yoktur:
upres, err := client.Database("user").Collection("users").ReplaceOne(ctx, bson.D{
{"age", 10},
},
bson.D{
{"address", "cn"},
})
if err != nil {
log.Panicln(err)
}
fmt.Printf("%+v", upres)Aynı zamanda mongo, doküman almak ve doküman güncellemek için FindOneAndUpdate ve FindOneAndReplace sağlar. Aşağıdaki gibi:
res := client.Database("user").Collection("users").FindOneAndReplace(ctx, bson.D{
{"address", "cn"},
},
bson.D{
{"address", "uk"},
})
if err := res.Err(); err != nil {
log.Panicln(err)
}
var user User
res.Decode(&user)
fmt.Printf("%+v", user)Çıktı
Name: Age:0 Address:cn}Bu işlem önce dokümanı sorgular, ardından dokümanı değiştirir.
Doküman Silme
Resmi silme örneği: mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)
Aşağıda bir doküman silme örneği bulunmaktadır:
result, err := client.Database("user").Collection("users").DeleteOne(ctx, bson.D{
{"name", "jack"},
})
if err != nil {
log.Panicln(err)
}
fmt.Println(result.DeletedCount)Aşağıda birden fazla doküman silme örneği bulunmaktadır:
result, err := client.Database("user").Collection("users").DeleteMany(ctx, bson.D{
{"age", "10"},
})
if err != nil {
log.Panicln(err)
}
fmt.Println(result.DeletedCount)Toplama (Aggregation)
Resmi toplama örneği: mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)
Toplama işleminde mongo.Pipeline türü kullanılır. Bu aslında []bson.D türüdür:
type Pipeline []bson.Dpipline := mongo.Pipeline{
{
{"$match", bson.D{
{"address", "uk"},
}},
},
{
{"$sort", bson.D{
{"age", 1},
}},
},
}
aggregate, err := client.Database("user").Collection("users").Aggregate(ctx, pipline)
if err != nil {
log.Panicln(err)
}
var users []User
if err := aggregate.All(ctx, &users); err != nil {
log.Panicln(err)
}
log.Println(users)Çıktı
[{lili 20 uk} {kak 30 uk}]Bu toplama işlemi, address'i uk olan tüm kullanıcıları eşleştirir ve ardından yaşa göre sıralar.
