不管任何数据库,查都是最复杂的操作。
基本查询,并且解析成结构体:
// 最基本的查询,一个查询条件即可,参考:https://www.mongodb.com/docs/manual/tutorial/query-documents/
func Find(mongo *mongo.Database, ctx context.Context) {
baseAdd := create.BaseAdd{}
filter := bson.M{} // 空结构体匹配所有
// 查询数据,并解析成结构体
err := mongo.Collection("test").FindOne(ctx, filter).Decode(&baseAdd)
if err != nil {
fmt.Println("err")
}
fmt.Println(baseAdd)
}
匹配多个值,且解析成结构体数组:
// 用$in关键字查询有多个值的情况
func FindIn(mongo *mongo.Database, ctx context.Context) {
filter := bson.M{"int32": bson.M{"$in": bson.A{math.MaxInt32, math.MaxInt32 - 1}}}
cur, err := mongo.Collection("test").Find(ctx, filter)
if err != nil {
fmt.Println("err")
}
// 多个文档解析程数组的方法
var baseAdd []create.BaseAdd
err = cur.All(ctx, &baseAdd)
fmt.Println(err)
fmt.Println(baseAdd)
}
大于和等于的匹配查询,并遍历结果:
// 用gt和lt关键字查询大于和小于,后面加个e表示等于
func FindGteAndLte(mongo *mongo.Database, ctx context.Context) {
// 多个条件是隐式的and关系,表示要同时满足全部条件
filter := bson.M{"int32": bson.M{"$gte": math.MaxInt32 - 1, "$lt": math.MaxInt32}}
cur, err := mongo.Collection("test").Find(ctx, filter)
if err != nil {
fmt.Println("err")
}
// 遍历数据
for cur.TryNext(ctx) {
result, _ := cur.Current.Elements()
fmt.Println(result)
}
cur.Close(ctx)
}
通常我们查询条件都是隐式and关系,可以使用or关键字表示多个条件只需满足其一:
// or对应的是个数组,只要满足数组里任一条件都可
filter := bson.M{"$or": bson.A{bson.M{"int32": bson.M{"$gte": math.MaxInt32 - 1}}, bson.M{"int32": bson.M{"$lt": math.MaxInt32}}}}
嵌套字段的查询匹配:
filter := bson.M{"object.id": 2} // 直接用点连接就好,没什么区别
之前的查询我们都是返回所有字段,还可以选择查询指定字段:
// 1表示只查询id字段,但是,主键_id会默认查询出来
options := options.FindOptions{Projection: bson.M{"id": 1}}
// 所以还可以加上"_id": 0排除主键
options := options.FindOptions{Projection: bson.M{"id": 1, "_id": 0}}
与上面相反,可以指定一个字段不要,查询剩余字段:
// 排除_id,其他字段都会被查出来,可以排除多个
options := options.FindOptions{Projection: bson.M{"_id": 0}}
对于嵌套的文档也同样受用,且用LookupErr遍历时,仅获取想要的key值:
// 对于嵌套的文档也同样受用
func FindChildField(mongo *mongo.Database, ctx context.Context) {
filter := bson.M{} // 空结构体匹配所有
// 嵌套字段也一样这么查
options := options.FindOptions{Projection: bson.M{"object.id": 1, "_id": 0}}
cur, err := mongo.Collection("test").Find(ctx, filter, &options)
if err != nil {
fmt.Println("err")
}
// 遍历数据
for cur.TryNext(ctx) {
result, _ := cur.Current.LookupErr("object")
fmt.Println(result)
}
cur.Close(ctx)
}