inital commit

This commit is contained in:
2024-12-12 15:55:37 +03:00
commit 13c18e116a
17 changed files with 858 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
mongo_crud

64
.golangci.yml Normal file
View File

@@ -0,0 +1,64 @@
linters-settings:
govet:
check-shadowing: true
gocyclo:
min-complexity: 20
maligned:
suggest-new: true
dupl:
threshold: 200
goconst:
min-len: 2
min-occurrences: 2
misspell:
locale: US
lll:
line-length: 140
goimports:
local-prefixes: github.com/golangci/golangci-lint
gocritic:
enabled-tags:
- performance
- style
- experimental
disabled-checks:
- wrapperFunc
linters:
disable-all: true
enable:
- govet
- gocyclo
- dupl
- lll
- gosec
- dupl
- goconst
# - depguard
- misspell
- goimports
# - gocritic
- staticcheck
- deadcode
- errcheck
- unused
- gosimple
- structcheck
- varcheck
- ineffassign
- typecheck
- bodyclose
- unconvert
- unparam
- prealloc
- whitespace
- exportloopref
run:
tests: false
go: "1.21"
skip-dirs:
- swagger-ui
- configs
- templates
- \.go

23
Makefile Normal file
View File

@@ -0,0 +1,23 @@
start:
docker compose -p mongo -f deployments/docker-compose.yml up -d
stop:
docker compose -p mongo down
clean:
rm -f ./mongo_crud
build: clean
go build .
run: build
./mongo_crud
mongosh:
mongosh "mongodb://root:example@127.0.0.1:27017/?authSource=admin"
aggregate:
mongosh "mongodb://root:example@127.0.0.1:27017/?authSource=admin" --file aggregate.js
import:
mongoimport --db=strava --collection=workout "mongodb://root:example@127.0.0.1:27017/?authSource=admin" backup.json

40
aggregate.js Normal file
View File

@@ -0,0 +1,40 @@
db = connect( 'mongodb://root:example@127.0.0.1:27017/strava?authSource=admin' );
let result = db.workout.aggregate([{
$match: {
type: 'Run'
}
}, {
$set: {
date: {
$dateFromString: {
dateString: '$start_date'
}
}
}
}, {
$group: {
_id: {
$dateToString: {
format: '%Y-%m',
date: '$date'
}
},
totalMonthDistance: {
$sum: {
$divide: [
'$distance',
1000
]
}
}
}
}, {
$match: {
totalMonthDistance: {
$gte: 150
}
}
}]);
console.log(result);

53
command.js Normal file
View File

@@ -0,0 +1,53 @@
db.books.insertOne({
title: 'gRPC: запуск и эксплуатация облачных приложений. Go и Java для Docker и Kubernetes',
author: 'Касун Индрасири',
year: 2020
})
db.books.insertMany([
{ title: 'Go: идиомы и паттерны проектирования', author: 'Боднер Джон', year: 2022 },
{
title: 'Высоконагруженные приложения. Программирование, масштабирование, поддержка',
author: 'Клеппман Мартин',
year: 2021
}
])
// Найти все документы
db.books.find()
// Найти документы по совпадению конкретного поля
db.books.find({ year: 2021 })
// Найти документы по условию на кокретное поле
db.books.find({ year: { $gte: 2021 } })
// Найти документы по условию на кокретное поле и вернуть первый
db.books.findOne({ year: { $gte: 2021 } })
// Найти документа по одному ИЛИ по второму условию.
db.books.find({ $or: [{ year: { $gte: 2021 } }, { author: 'Касун Индрасири' }] })
db.books.findOne({ year: { $gte: 2021 } }, { title: 1, _id: 0 })
db.books.findOne({ year: { $gte: 2021 } }, { title: 0, _id: 0 })
db.books.updateOne(
{
title: 'Высоконагруженные приложения. Программирование, масштабирование, поддержка'
},
{ $set: { rating: 5 } }
)
db.books.updateMany({ rating: null }, { $set: { rating: 3 } })
db.books.replaceOne(
{ author: 'Ньюмен Сэм' },
{
title: 'Создание микросервисов',
author: 'Ньюмен Сэм',
year: 2016,
rating: 3
},
{ upsert: true }
)
db.books.countDocuments()
db.books.deleteOne({ author: 'Ньюмен Сэм' })
db.books.deleteMany({ rating: { $lt: 5 } })

24
delete.go Normal file
View File

@@ -0,0 +1,24 @@
package main
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
func deleteAllRows(ctx context.Context, coll *mongo.Collection) {
ctx, span := FollowSpan(ctx, "deleteAllRows")
defer span.End()
result, err := coll.DeleteMany(ctx, bson.D{})
if err != nil {
log.Fatal(result)
}
fmt.Println("Remove all documents...")
fmt.Printf("%d documents removed\n", result.DeletedCount)
fmt.Println("=============================")
}

View File

@@ -0,0 +1,41 @@
version: "3.9"
services:
mongo:
image: "mongo"
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: example
ME_CONFIG_MONGODB_URL: mongodb://root:example@mongo:27017/
otel-collector:
image: otel/opentelemetry-collector:latest
container_name: otel-collector
command: ["--config=/etc/otel-collector-config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- "4317:4317"
depends_on:
- jaeger
jaeger:
image: jaegertracing/all-in-one:latest
container_name: jaeger
environment:
- COLLECTOR_OTLP_ENABLED=true
- COLLECTOR_OTLP_GRPC_HOST-PORT=:4317
- COLLECTOR_OTLP_GRPC_HOST_PORT=:4317
ports:
- "16686:16686"

View File

@@ -0,0 +1,19 @@
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
exporters:
otlp:
endpoint: "http://jaeger:4317"
tls:
insecure: true
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
processors: []
exporters: [otlp, debug]

110
find.go Normal file
View File

@@ -0,0 +1,110 @@
package main
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func checkFindErr(err error) {
if err != nil {
if err == mongo.ErrNoDocuments {
return
}
log.Fatal(err)
}
}
func findAll(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "findAll")
defer span.End()
fmt.Println("replaceOne document...")
cursor, err := col.Find(ctx, bson.M{})
checkFindErr(err)
var books []Book
err = cursor.All(ctx, &books)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Finded %d docs:\n%v\n", len(books), books)
fmt.Println("=============================")
}
func find(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "find")
defer span.End()
opts := options.Find().SetSort(bson.M{"rating": 1})
cursor, err := col.Find(ctx, bson.M{"year": 2022}, opts)
checkFindErr(err)
var books []Book
err = cursor.All(ctx, &books)
if err != nil {
log.Fatal(err)
}
fmt.Println("Search documents where year equal 2022...")
fmt.Printf("Finded %d docs:\n%v\n", len(books), books)
fmt.Println("=============================")
}
func findWithCondition(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "findWithCondition")
defer span.End()
filter := bson.M{"year": bson.M{"$gt": 2020}}
cursor, err := col.Find(ctx, filter)
checkFindErr(err)
var books []Book
err = cursor.All(ctx, &books)
if err != nil {
log.Fatal(err)
}
fmt.Println("Search documents where year greather then 2020...")
fmt.Printf("Finded %d docs:\n%v\n", len(books), books)
fmt.Println("=============================")
}
func findWithOrCondition(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "findWithOrCondition")
defer span.End()
filter := bson.M{
"$or": bson.A{
bson.M{
"year": bson.M{"$gte": 2020},
},
bson.M{
"author": "Касун Индрасири",
},
},
}
findOptions := options.Find()
findOptions.SetProjection(bson.M{"author": 0})
cursor, err := col.Find(ctx, filter, findOptions)
checkFindErr(err)
var books []Book
err = cursor.All(ctx, &books)
if err != nil {
log.Fatal(err)
}
fmt.Println("Search documents where year greather then 2020 AND author is 'Касун Индрасири'...")
fmt.Printf("Finded %d docs:\n%v\n", len(books), books)
fmt.Println("=============================")
}

40
go.mod Normal file
View File

@@ -0,0 +1,40 @@
module github.com/maksim77/mongo_crud
go 1.21
require (
go.mongodb.org/mongo-driver v1.13.0
go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo v0.46.0
go.opentelemetry.io/otel v1.20.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0
go.opentelemetry.io/otel/sdk v1.20.0
go.opentelemetry.io/otel/trace v1.20.0
google.golang.org/grpc v1.59.0
)
require (
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 // indirect
github.com/klauspost/compress v1.17.2 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.opentelemetry.io/otel/metric v1.20.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/crypto v0.15.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)

117
go.sum Normal file
View File

@@ -0,0 +1,117 @@
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 h1:6UKoz5ujsI55KNpsJH3UwCq3T8kKbZwNZBNPuTTje8U=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1/go.mod h1:YvJ2f6MplWDhfxiUC3KpyTy76kYUZA4W3pTv/wdKQ9Y=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.13.0 h1:67DgFFjYOCMWdtTEmKFpV3ffWlFnh+CYZ8ZS/tXWUfY=
go.mongodb.org/mongo-driver v1.13.0/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo v0.46.0 h1:1b/GR0eOpqQJ0kjJeuzDwqUzcQD3cnZgsAPlG8032BQ=
go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo v0.46.0/go.mod h1:2nM/khnHtYdbPG/3dWxS8RN+t8/OChavUx5JZHdgAEM=
go.opentelemetry.io/otel v1.20.0 h1:vsb/ggIY+hUjD/zCAQHpzTmndPqv/ml2ArbsbfBYTAc=
go.opentelemetry.io/otel v1.20.0/go.mod h1:oUIGj3D77RwJdM6PPZImDpSZGDvkD9fhesHny69JFrs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0 h1:DeFD0VgTZ+Cj6hxravYYZE2W4GlneVH81iAOPjZkzk8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0 h1:gvmNvqrPYovvyRmCSygkUDyL8lC5Tl845MLEwqpxhEU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0=
go.opentelemetry.io/otel/metric v1.20.0 h1:ZlrO8Hu9+GAhnepmRGhSU7/VkpjrNowxRN9GyKR4wzA=
go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM=
go.opentelemetry.io/otel/sdk v1.20.0 h1:5Jf6imeFZlZtKv9Qbo6qt2ZkmWtdWx/wzcCbNUlAWGM=
go.opentelemetry.io/otel/sdk v1.20.0/go.mod h1:rmkSx1cZCm/tn16iWDn1GQbLtsW/LvsdEEFzCSRM6V0=
go.opentelemetry.io/otel/trace v1.20.0 h1:+yxVAPZPbQhbC3OfAkeIVTky6iTFpcr4SiY9om7mXSQ=
go.opentelemetry.io/otel/trace v1.20.0/go.mod h1:HJSK7F/hA5RlzpZ0zKDCHCDHm556LCDtKaAo6JmBFUU=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ=
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY=
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo=
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17 h1:Jyp0Hsi0bmHXG6k9eATXoYtjd6e2UzZ1SCn/wIupY14=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

12
helpers.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import (
"context"
"go.opentelemetry.io/otel/trace"
)
func FollowSpan(ctx context.Context, name string) (_ context.Context, span trace.Span) {
ctx, span = tracer.Start(ctx, name)
return ctx, span
}

58
insert.go Normal file
View File

@@ -0,0 +1,58 @@
package main
import (
"context"
"encoding/binary"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
func insertOne(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "insertOne")
defer span.End()
fmt.Println("Inserting 1 documents...")
result, err := col.InsertOne(ctx, book)
if err != nil {
log.Fatal(err)
}
fmt.Printf("One document inserted with id: %s\n", result.InsertedID)
fmt.Println("=============================")
}
func insertMany(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "insertMany")
defer span.End()
fmt.Println("Inserting 2 documents...")
inserts := make([]interface{}, 0, len(books))
for _, book := range books {
inserts = append(inserts, book)
}
result, err := col.InsertMany(ctx, inserts)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%d documents inserted with ids: %v\n", len(result.InsertedIDs), result.InsertedIDs)
// ObjectID описание
for _, v := range result.InsertedIDs {
id := [12]byte(v.(primitive.ObjectID))
byteTime := id[0:4]
byteRandomID := id[4:9]
byteInc := id[9:12]
fmt.Printf("Timestamp: %d\n", binary.BigEndian.Uint32(byteTime))
fmt.Printf("Timestamp to date: %v\n", time.Unix(int64(binary.BigEndian.Uint32(byteTime)), 0))
fmt.Printf("Random val per process and machine: %d\n", binary.BigEndian.Uint32(byteRandomID))
fmt.Printf("Inc counter: %d\n", binary.BigEndian.Uint16(byteInc))
fmt.Println("*******")
}
fmt.Println("=============================")
}

93
main.go Normal file
View File

@@ -0,0 +1,93 @@
package main
import (
"context"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo"
"go.opentelemetry.io/otel"
)
var tracer = otel.Tracer("mongo_example")
const URI = "mongodb://127.0.0.1:27017"
func getClient(ctx context.Context) (*mongo.Client, error) {
ctx, span := FollowSpan(ctx, "getClient")
defer span.End()
opts := options.Client()
opts.ApplyURI(URI)
optsAuth := options.Credential{
Username: "root",
Password: "example",
AuthSource: "admin",
}
opts.SetAuth(optsAuth)
opts.Monitor = otelmongo.NewMonitor()
client, err := mongo.Connect(ctx, opts)
if err != nil {
return nil, err
}
return client, nil
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
shutdown, err := InstallExportPipeline()
if err != nil {
log.Fatal(err.Error())
}
defer func() {
if err := shutdown(context.Background()); err != nil {
log.Fatal(err.Error())
}
}()
// =========
// ==START==
// =========
ctx, span := tracer.Start(ctx, "main")
defer span.End()
// Создаём клиента
client, err := getClient(ctx)
if err != nil {
log.Println(err)
return
}
defer func() {
if mongoDisconectErr := client.Disconnect(ctx); mongoDisconectErr != nil {
log.Println(mongoDisconectErr)
}
}()
// Все примеры будут для одной колллекции поэтому сразу создаём соответствующий объект
col := client.Database("teta").Collection("books")
// Чтобы точно начать с чистого листа удалим коллекцию вообще.
err = col.Drop(ctx)
if err != nil {
log.Fatal(err)
}
insertOne(ctx, col)
insertMany(ctx, col)
findAll(ctx, col)
find(ctx, col)
findWithCondition(ctx, col)
findWithOrCondition(ctx, col)
updateOne(ctx, col)
updateMany(ctx, col)
replaceOne(ctx, col)
deleteAllRows(ctx, col)
}

33
model.go Normal file
View File

@@ -0,0 +1,33 @@
package main
import "fmt"
type Book struct {
Title string `bson:"title"`
Author string `bson:"author"`
Year int `bson:"year"`
Rating int `bson:"rating"`
}
func (b Book) String() string {
return fmt.Sprintf("{\n\tTtile: %s,\n\tAuthor: %s\n\tYear: %d\n\tRating: %d\n}\n", b.Title, b.Author, b.Year, b.Rating)
}
var book Book = Book{
Title: "gRPC: запуск и эксплуатация облачных приложений. Go и Java для Docker и Kubernetes",
Author: "Касун Индрасири",
Year: 2020,
}
var books []Book = []Book{
{
Title: "Go: идиомы и паттерны проектирования",
Author: "Боднер Джон",
Year: 2022,
},
{
Title: "Высоконагруженные приложения. Программирование, масштабирование, поддержка",
Author: "Клеппман Мартин",
Year: 2021,
},
}

55
observability.go Normal file
View File

@@ -0,0 +1,55 @@
package main
import (
"context"
"fmt"
"log"
"time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)
func InstallExportPipeline() (func(context.Context) error, error) {
traceClient := otlptracegrpc.NewClient(
otlptracegrpc.WithInsecure(),
otlptracegrpc.WithEndpoint("127.0.0.1:4317"),
)
sctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
traceExp, err := otlptrace.New(sctx, traceClient)
if err != nil {
log.Fatal(err)
}
if err != nil {
return nil, fmt.Errorf("creating stdout exporter: %w", err)
}
res, err := resource.New(context.Background(),
resource.WithFromEnv(),
resource.WithProcess(),
resource.WithTelemetrySDK(),
resource.WithHost(),
resource.WithAttributes(
semconv.ServiceNameKey.String("go_test"),
),
)
if err != nil {
log.Fatal(err)
}
tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(traceExp),
sdktrace.WithResource(res),
)
otel.SetTracerProvider(tracerProvider)
otel.SetTextMapPropagator(propagation.TraceContext{})
return tracerProvider.Shutdown, nil
}

75
update.go Normal file
View File

@@ -0,0 +1,75 @@
package main
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func updateOne(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "updateOne")
defer span.End()
filter := bson.M{
"title": "Высоконагруженные приложения. Программирование, масштабирование, поддержка",
}
update := bson.M{
"$set": bson.M{"rating": 5},
}
result, err := col.UpdateOne(ctx, filter, update)
if err != nil {
log.Fatal(err)
}
fmt.Println("Updating 1 documents...")
fmt.Printf("Matched docs: %d. Updated docs: %d\n", result.MatchedCount, result.ModifiedCount)
fmt.Println("=============================")
}
func updateMany(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "updateMany")
defer span.End()
filter := bson.M{
"rating": 0,
}
update := bson.M{
"$set": bson.M{"rating": 3},
}
result, err := col.UpdateMany(ctx, filter, update)
if err != nil {
log.Fatal(err)
}
fmt.Println("Updating many documents...")
fmt.Printf("Matched docs: %d. Updated docs: %d\n", result.MatchedCount, result.ModifiedCount)
fmt.Println("=============================")
}
func replaceOne(ctx context.Context, col *mongo.Collection) {
ctx, span := FollowSpan(ctx, "replaceOne")
defer span.End()
fmt.Println("replaceOne document...")
var updatedBook Book = Book{
Author: "Ньюмен Сэм",
Title: "Создание микросервисов",
Year: 2016,
}
result, err := col.ReplaceOne(ctx, bson.M{"author": "Ньюмен Сэм"}, updatedBook, options.Replace().SetUpsert(true))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Matched docs: %d. Updated docs: %d. Upserted docs: %d\n", result.MatchedCount, result.ModifiedCount, result.UpsertedCount)
fmt.Println("=============================")
}