目 录CONTENT

文章目录

MongoDB基本概念与使用

Sakura
2024-03-02 / 0 评论 / 0 点赞 / 36 阅读 / 10960 字 / 正在检测是否收录...

MongoDB基本概念与使用

MongoDB官方文档:MongoDB Documentation

1.

2. 基本操作

2.1 数据库

# 选择或创建数据库(如果没有数据库会直接创建)
use 数据库名

# 查看有权限查看的所有数据库
show dbs

# 删除数据库
 db.dropDatabase()

admin : 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。

local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合

config : 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息

3. 集合

3.1 删除集合

db.<集合>.drop()

使用drop 之后所有文档相关的索引都会删除

3.2 插入

# 插入单个
db.<集合>.insertOne(<JSON对象>)
# 插入多个
db.<集合>.insertMany(<JSON对象>)


# 示例
db.fruit.insertOne({name: "apple"})
{
  acknowledged: true,
  insertedId: ObjectId('65ec8a0ad4e4510dcf3f07ca')
}

db.fruit.insertMany([{name: "orange"},{name: "banana"},{name: "pear"}])
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('65ec8a8fd4e4510dcf3f07cb'),
    '1': ObjectId('65ec8a8fd4e4510dcf3f07cc'),
    '2': ObjectId('65ec8a8fd4e4510dcf3f07cd')
  }
}

3.3 查询

# 单条件查询
db.movies.find({"year":1975}) 

# 多条件and查询
db.movies.find({"year":1989,"title":"Batman"})
# and的另一种形式
db.movies.find({$and:[{"title":"Batman"},{"category":"action"H}) 

# 多条件or查询
db.movies.find({$or:[{"year":1989},""title":"Batman"]})

# 按正则表达式查找
db.movies.find({"title":/^B/})

和 Mysql 查询逻辑对照表

查询子文档

# form 中包含一个子文档
db.fruit.insertOne ({
	name:"apple",
	from: {
		country:"China",
		province:"Guangdon"
	}
})

# 想要查询子文档
db.fruit.find( {"from.country": "China"} ) # 写文档的路径
db.fruit.find( {"from": { country: "China" } } ) # 不正确的写法

查询数组

# 文档color字段是数组
db.fruit.insertOne ([
	{"name": "Apple", color: ["red", "green"] },
	{"name": "Mango", color: ["yellow", "green"] }
])

# 查找color字段里面有红色的
db.fruit.find({ color: "red" })

# 查找color字段里面有红色或者黄色的
db.fruit.find({$or: [{color: "red" }, {color: "yellow"}]}) 

查询数组中的对象

db.movies.insertOne( {
	"title":"Raiders of the Lost Ark",
	"filming_locations": [
		{"city": "Los Angeles", "state": "CA", "country": "USA" },
		{"city": "Rome", "state": "Lazio", "country": "Italy"},
		{"city": "Florence", "state": "SC", "country":"USA"},
	]
})

// 查找城市是Rome的记录
db.movies.find({"filming_locations.city": "Rome"})

  • $eleMatch,表示必须是同一个子对象满足多个条件,考虑一下两个查询

# 匹配那些数组中任意元素满足 city 为 Rome 和 数组中另一个元素满足 country 为 USA 的文档
db.getCollection('movies').find({
	"filming_locations.city":"Rome",
	"filming_locations.country":"USA"
})

# 使用 $elemMatch 操作符时,它会确保在 filming_locations 数组内的单个元素内同时满足 city 为 "Rome" 和 country 为 "USA" 这两个条件。
db.getCollection('movies').find({
	"filming_locations": {
	SelemMatch:{"city":"Rome","country":"USA"}
})

控制返回的字段

# _id:0 表示不返回id字段
# from:1 表示返回from字段
# 并且只返回指定的字段
db.fruit.find({"name": "apple"},{"_id":0, from:1})

3.4 删除

remove 需要配合查询条件使用,并且如果指定空条件会删除所有文档

# 删除a等于1的文档
db.fruit.remove({a:1})

# 删除a小于1的文档
db.fruit.remove({a: { $lt: 5 })

# 删除所有记录(空的删除条件)
db.fruit.remove({})

# 报错,因为没有指定删除条件
db.furit.remove()

3.5 更新

# 查询name为apple的记录
# 将记录的from字段设置为China
db.fruit.updateOne({name: "apple"}, {$set: {from: "China"}})
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

注意事项:

  1. updateOne 无论匹配了多少条,只更新第一条

  2. updateMany 匹配多少条,更新多少条

4. Mongodb go 客户端使用

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

var client *mongo.Client

// Replace the placeholder with your Atlas connection string
const uri = "mongodb://mongo_E352Yy:mongo_3DhYJ6@xxx.xxx.xxx.xxx:27017/?maxPoolSize=20&w=majority"

func init() {
	// 设置客户端连接选项
	opts := options.Client().ApplyURI(uri)
	opts.SetConnectTimeout(3 * time.Second)

	// 连接到 MongoDB
	var err error
	client, err = mongo.Connect(context.Background(), opts)
	if err != nil {
		log.Fatalf("Failed to connect to MongoDB: %v", err)
	}

	// 检查连接是否成功
	err = client.Ping(context.Background(), nil)
	if err != nil {
		log.Fatalf("Failed to ping MongoDB: %v", err)
	}
	log.Println("Connected to MongoDB")
}
  • 依赖注入方式管理mongoDB连接

// Mongo   是一个抽象的MongoDB客户端接口
type Mongo interface {
	GetClient() (*mongo.Client, error)
	Close(context.Context) error
}

// MongoDBClient 实现了MongoDBClientInterface接口
type MongoDBClient struct {
	client *mongo.Client
}

// NewMongoDBClient   是一个工厂函数,它负责初始化MongoDB客户端并返回其接口
func NewMongoDBClient(cfg *MongoDBConfig) (Mongo, error) {
	ctx := context.Background()
	clientOptions := options.Client().ApplyURI(cfg.Uri)

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

	err = client.Ping(ctx, nil)
	if err != nil {
		defer client.Disconnect(ctx)
		return nil, err
	}
	fmt.Println("Connected to MongoDB")

	return &MongoDBClient{client: client}, nil
}

// "mongodb://mongo_E352Yy:mongo_3DhYJ6@xxx.xxx.xxx.xxx:27017/?maxPoolSize=20&w=majority"
type MongoDBConfig struct {
	Uri         string `yaml:"uri"`
	Address     string `yaml:"address"`
	Username    string `yaml:"username"`
	Password    string `yaml:"password"`
	MaxPoolSize int    `yaml:"maxPoolSize"`
}

func GetMongoDBConfig() (*MongoDBConfig, error) {
	config := new(MongoDBConfig)
	file, err := os.ReadFile("mongodb.yaml")
	if err != nil {
		return nil, err
	}
	//fmt.Println(string(file))
	err = yaml.Unmarshal(file, config)
	if err != nil {
		return nil, err
	}

	config.Uri = fmt.Sprintf("mongodb://%s:%s@%s/?maxPoolSize=%d", config.Username, config.Password, config.Address, config.MaxPoolSize)
	return config, nil
}

// GetClient 返回已连接的MongoDB客户端实例
func (mc *MongoDBClient) GetClient() (*mongo.Client, error) {
	return mc.client, nil
}

// Close 断开与MongoDB的连接
func (mc *MongoDBClient) Close(ctx context.Context) error {
	return mc.client.Disconnect(ctx)
}

编写 wire.go 文件

//go:build wireinject
// +build wireinject

package MongDB

import (
	"github.com/google/wire"
)

func InitializeService() (*MyService, error) {

	panic(wire.Build(
		GetMongoDBConfig,
		NewMongoDBClient,
		NewMyService,
	))
}

生成的 wire_gen.go 文件

// Code generated by Wire. DO NOT EDIT.

//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package MongDB

// Injectors from wire.go:

func InitializeService() (*MyService, error) {
	mongoDBConfig, err := GetMongoDBConfig()
	if err != nil {
		return nil, err
	}
	mongo, err := NewMongoDBClient(mongoDBConfig)
	if err != nil {
		return nil, err
	}
	myService := NewMyService(mongo)
	return myService, nil
}

5. 聚合查询

Mysql 常用步骤和 SQL 对比

0

评论区