В этом посте мы рассмотрим простое приложение Golang, которое демонстрирует, как выполнять основные операции CRUD в базе данных MongoDB. Приведенный ниже фрагмент кода создает оболочку для клиента MongoDB, позволяя легко выполнять действия по созданию, чтению, обновлению и удалению.

Настройка

Если вы хотите запустить mongodb из докера, вы можете использовать следующий yaml:

version: '3.8'

services:
  mongodb:
    image: mongo:latest
    container_name: mongodb
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example_password
    ports:
      - "27017:27017"
    volumes:
      - mongodb_data:/data/db

volumes:
  mongodb_data:

Пример на ходу

Структура MongoDB — это оболочка для клиента MongoDB, предоставляющая удобные методы для выполнения операций CRUD. Функция NewMongoDB инициализирует новый клиент MongoDB и подключается к базе данных.

Функция AddDocument вставляет новый документ в указанную базу данных и коллекцию. Функция FindDocument извлекает документ по его ключу (поле _id). Функция FindDocumentsWithFilters находит все документы, соответствующие заданному фильтру, и возвращает массив соответствующих документов. Функция DeleteDocument удаляет документ по его ключу.

Функция main демонстрирует, как использовать структуру MongoDB путем подключения к экземпляру MongoDB, добавления нескольких документов в коллекцию, поиска одного документа по его ключу, использования фильтров для поиска нескольких документов и удаления документов по их ключам.

В примере четыре документа с разными ключами и значениями добавляются в коллекцию «example» в базе данных «test». Фильтр bson.M{"value": "my_value"} используется для поиска документов с полем value, для которого задано значение my_value. После выполнения функции main приложение распечатает результаты добавления, поиска и удаления документов.

Фрагмент кода

package main

import (
 "context"
 "fmt"
 "go.mongodb.org/mongo-driver/bson"
 "go.mongodb.org/mongo-driver/mongo"
 "go.mongodb.org/mongo-driver/mongo/options"
 "log"
 "time"
)

// MongoDB is a wrapper around the MongoDB client
// that provides some basic CRUD operations.
type MongoDB struct {
 client *mongo.Client
}

// NewMongoDB creates a new MongoDB client.
func NewMongoDB(uri string) (*MongoDB, error) {
 client, err := mongo.NewClient(options.Client().ApplyURI(uri))
 if err != nil {
  return nil, err
 }

 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 defer cancel()

 err = client.Connect(ctx)
 if err != nil {
  return nil, err
 }

 return &MongoDB{client: client}, nil
}

// AddDocument adds a document to the database.
func (mdb *MongoDB) AddDocument(database, collection string, document bson.M) error {
 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancel()

 coll := mdb.client.Database(database).Collection(collection)
 _, err := coll.InsertOne(ctx, document)
 return err
}

// FindDocument finds a document by key.
func (mdb *MongoDB) FindDocument(database, collection string, key string) (bson.M, error) {
 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancel()

 coll := mdb.client.Database(database).Collection(collection)
 filter := bson.M{"_id": key}

 var result bson.M
 err := coll.FindOne(ctx, filter).Decode(&result)

 return result, err
}

// FindDocumentsWithFilters finds documents that match the provided filter.
func (mdb *MongoDB) FindDocumentsWithFilters(database, collection string,
 filter bson.M) ([]bson.M, error) {
 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancel()

 coll := mdb.client.Database(database).Collection(collection)

 cursor, err := coll.Find(ctx, filter)
 if err != nil {
  return nil, err
 }
 defer cursor.Close(ctx)

 var results []bson.M
 err = cursor.All(ctx, &results)
 if err != nil {
  return nil, err
 }

 return results, nil
}

// DeleteDocument deletes a document by key.
func (mdb *MongoDB) DeleteDocument(database, collection string, key string) error {
 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
 defer cancel()

 coll := mdb.client.Database(database).Collection(collection)
 filter := bson.M{"_id": key}

 _, err := coll.DeleteOne(ctx, filter)
 return err
}

func (mdb *MongoDB) Close() {
 _ = mdb.client.Disconnect(context.Background())
}

func main() {
 mongoDB, err := NewMongoDB("mongodb://root:example_password@localhost:27017")
 if err != nil {
  log.Fatalf("Failed to connect to MongoDB: %v", err)
 }
 defer mongoDB.Close()

 db := "test"
 coll := "example"

 // Add multiple documents
 documents := []bson.M{
  {"_id": "key1", "value": "my_value", "pi": 3.14159},
  {"_id": "key2", "value": "my_value", "pi": 3.14159},
  {"_id": "key3", "value": "another_value", "pi": 3.14159},
  {"_id": "key4", "value": "another_value", "pi": 2.71828},
 }

 for _, document := range documents {
  err = mongoDB.AddDocument(db, coll, document)
  if err != nil {
   log.Fatalf("Failed to add document: %v", err)
  }
  fmt.Println("Added document:", document)
 }

 // Find the document by key
 key := "key1"
 found, err := mongoDB.FindDocument(db, coll, key)
 if err != nil {
  log.Fatalf("Failed to find document: %v", err)
 }
 fmt.Println("Found document:", found)

 // Find documents with filters
 filter := bson.M{"value": "my_value"}
 filteredDocs, err := mongoDB.FindDocumentsWithFilters(db, coll, filter)
 if err != nil {
  log.Fatalf("Failed to find documents with filters: %+v", err)
 }
 fmt.Println("Found documents with filters:", filteredDocs)

 // Delete the documents by key
 for _, document := range documents {
  err = mongoDB.DeleteDocument(db, coll, document["_id"].(string))
  if err != nil {
   log.Fatalf("Failed to delete document: %v", err)
  }
  fmt.Println("Deleted document:", document["_id"])
 }
}

И результаты, которые мы имеем после запуска main

Заключение

Это простое приложение Golang демонстрирует, как взаимодействовать с MongoDB и выполнять операции CRUD. Используя оболочку для клиента MongoDB, вы можете создать более удобную и организованную кодовую базу. С помощью этой основы вы можете легко расширить приложение для поддержки более сложных вариантов использования и запросов.

Если вам нравится читать статьи на Medium и вы заинтересованы в том, чтобы стать участником, я буду рад поделиться с вами своей реферальной ссылкой!

https://medium.com/@adamszpilewicz/membership