Go MongoDB Model with Enum Validation for Brand Field
67 views
Sure, let's define a MongoDB model in Go where the Brand field can only be either "porta" or "boss". We'll follow the same steps as before:
- Define a custom type
Brand. - Define the possible values for
Brand. - Implement BSON marshalling and unmarshalling for the custom type.
- Define the MongoDB model that includes the
Brandfield.
Here is the complete code:
package main
import (
"context"
"fmt"
"os"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo/bson/bsontype"
)
// Brand type represents an enum
type Brand string
const (
BrandPorta Brand = "porta"
BrandBoss Brand = "boss"
)
// Implement BSON marshalling and unmarshalling
func (b Brand) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(string(b))
}
func (b *Brand) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
var str string
if err := bson.UnmarshalValue(t, data, &str); err != nil {
return err
}
*b = Brand(str)
return nil
}
// Document represents a MongoDB document
type Document struct {
ID string `bson:"_id,omitempty"`
Name string `bson:"name,omitempty"`
Brand Brand `bson:"brand,omitempty"`
}
func main() {
// MongoDB configuration
uri := "mongodb://localhost:27017"
clientOpts := options.Client().ApplyURI(uri)
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to connect to MongoDB: %v\n", err)
os.Exit(1)
}
defer func() {
if err := client.Disconnect(context.TODO()); err != nil {
fmt.Fprintf(os.Stderr, "Failed to disconnect from MongoDB: %v\n", err)
}
}()
collection := client.Database("testdb").Collection("documents")
// Create a document with Brand "porta"
doc := Document{
Name: "Sample Document",
Brand: BrandPorta,
}
// Insert the document
insertResult, err := collection.InsertOne(context.TODO(), doc)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to insert document: %v\n", err)
os.Exit(1)
}
fmt.Printf("Inserted document with ID: %v\n", insertResult.InsertedID)
// Retrieve the document
filter := bson.M{"name": "Sample Document"}
var retrievedDoc Document
err = collection.FindOne(context.TODO(), filter).Decode(&retrievedDoc)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to find document: %v\n", err)
os.Exit(1)
}
fmt.Printf("Retrieved document: %+v\n", retrievedDoc)
}
Explanation:
- Brand Type: Defined a new type
Brandwhich represents the enum. - Enum Values: Defined two constants
BrandPortaandBrandBossrepresenting the allowed values for theBrandtype. - BSON Handling: Implemented the
MarshalBSONValueandUnmarshalBSONValuemethods to correctly convert between theBrandtype and BSON. - Document Model: The
Documentstruct includes anID,Name, andBrandfield. - Database Operations: Connected to a MongoDB instance, inserted a document with a
Brandvalue, and retrieved it to demonstrate the proper handling of the enum in a MongoDB context.
This ensures that the Brand field in the model can only have values defined by the Brand type.