Golang中MongoDB的Schema验证实现与技巧
Golang中MongoDB的Schema验证实现与技巧 大家好,
我为MongoDB编写了以下模式验证器,以下是针对名为“posts”的集合的插入查询。基本思路是创建一个博客,包含标题、作者、标签和评论,其中评论是嵌套文档。 我能够成功运行验证器,但无法运行插入查询。模式验证失败了。
db.users.find()
{ _id: ObjectId("647b983d65af5108a7f21679"),
name: 'shubhra garg',
age: 34,
email_id: 'shubhra.garg09@gmail.com' }
{ _id: ObjectId("647b983d65af5108a7f2167a"),
name: 'ankit garg',
age: 29,
email_id: 'gargankit2201@gmail.com' }
{ _id: ObjectId("647b9b0865af5108a7f2167d"),
name: 'anita agrawal',
age: 44,
email_id: 'anita49@gmail.com' }
{ _id: ObjectId("647b9b0865af5108a7f2167e"),
name: 'sp agrawal',
age: 64,
email_id: 'spqagrawal@gmail.com' }
db.createCollection('posts',
{validator: {
$jsonSchema:{
bsonType:'object',
required:['title','text','author','comments'],
properties:{
title:{
bsonType:'string',
description:"Title is a required field"
},
text:{
bsonType:'string',
description:"Text field is required"
},
author:{
bsonType:'objectId',
description:"Author is required field"
},
comments:{
bsonType:'array',
description:"must be an array of list and is required field",
items:{
bsonType:'objectId',
required:['text','creator'],
properties:{
text:{
bsonType:'string',
description:"text is a required field"
},
creator:{
bsonType:'objectId',
description:"Creator field is required"
}
}
}
}
}
}
}
}
)
分享两个MongoDB的插入查询:
db.posts.insertOne({title: "My first post",text:"Happy me!", author:ObjectId("647b983d65af5108a7f21679"), tags:["new","generation","happy"], comments:[{text:"Good to see you happy", creator:ObjectId("647b983d65af5108a7f2167a")}]})
db.posts.insertOne({title: "My first post",text:"Happy me!", author:ObjectId("647b983d65af5108a7f21679"),comments:[{text:"Good to see you happy", creator:ObjectId("647b9b0865af5108a7f2167d")}]})
更多关于Golang中MongoDB的Schema验证实现与技巧的实战教程也可以访问 https://www.itying.com/category-94-b0.html
@christophberger 你能帮忙解决这个问题吗?我卡住了。
更多关于Golang中MongoDB的Schema验证实现与技巧的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
@Metalymph 你能帮忙看看这个模式验证的程序吗?
@shubhragrag 抱歉,我不得不拒绝。我对MongoDB的了解仅限于其名称以及它是一个面向文档的数据库这一事实。
第一个查询包含一个 tags 字段,我在 $jsonSchema 中没有看到这个字段,但乍看之下第二个查询似乎没问题。
失败的架构验证是否发出了任何有用的错误信息?
在MongoDB的JSON Schema验证中,你的模式存在几个关键问题。主要问题在于comments字段的验证规则定义不正确。
以下是修正后的模式验证器:
db.createCollection('posts', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['title', 'text', 'author', 'comments'],
properties: {
title: {
bsonType: 'string',
description: "Title is a required field"
},
text: {
bsonType: 'string',
description: "Text field is required"
},
author: {
bsonType: 'objectId',
description: "Author is required field"
},
tags: {
bsonType: 'array',
description: "Optional array of tags",
items: {
bsonType: 'string'
}
},
comments: {
bsonType: 'array',
description: "must be an array of comment objects",
items: {
bsonType: 'object',
required: ['text', 'creator'],
properties: {
text: {
bsonType: 'string',
description: "text is a required field"
},
creator: {
bsonType: 'objectId',
description: "Creator field is required"
}
}
}
}
}
}
}
})
主要修正点:
comments.items.bsonType应该是'object'而不是'objectId',因为每个评论是一个包含text和creator的对象- 添加了
tags字段的定义(虽然它不是必需的,但明确声明有助于文档结构清晰)
在Go中实现MongoDB插入时,可以使用以下代码示例:
package main
import (
"context"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Post struct {
ID primitive.ObjectID `bson:"_id,omitempty"`
Title string `bson:"title"`
Text string `bson:"text"`
Author primitive.ObjectID `bson:"author"`
Tags []string `bson:"tags,omitempty"`
Comments []Comment `bson:"comments"`
}
type Comment struct {
Text string `bson:"text"`
Creator primitive.ObjectID `bson:"creator"`
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
log.Fatal(err)
}
defer client.Disconnect(ctx)
collection := client.Database("test").Collection("posts")
// 创建验证器
validator := bson.M{
"$jsonSchema": bson.M{
"bsonType": "object",
"required": []string{"title", "text", "author", "comments"},
"properties": bson.M{
"title": bson.M{
"bsonType": "string",
"description": "Title is a required field",
},
"text": bson.M{
"bsonType": "string",
"description": "Text field is required",
},
"author": bson.M{
"bsonType": "objectId",
"description": "Author is required field",
},
"tags": bson.M{
"bsonType": "array",
"description": "Optional array of tags",
"items": bson.M{
"bsonType": "string",
},
},
"comments": bson.M{
"bsonType": "array",
"description": "must be an array of comment objects",
"items": bson.M{
"bsonType": "object",
"required": []string{"text", "creator"},
"properties": bson.M{
"text": bson.M{
"bsonType": "string",
"description": "text is a required field",
},
"creator": bson.M{
"bsonType": "objectId",
"description": "Creator field is required",
},
},
},
},
},
},
}
// 创建集合时应用验证器
opts := options.CreateCollection().SetValidator(validator)
err = client.Database("test").CreateCollection(ctx, "posts", opts)
if err != nil {
// 如果集合已存在,可以忽略这个错误
fmt.Printf("Collection creation error (may already exist): %v\n", err)
}
// 插入示例数据
authorID, _ := primitive.ObjectIDFromHex("647b983d65af5108a7f21679")
creatorID, _ := primitive.ObjectIDFromHex("647b983d65af5108a7f2167a")
post := Post{
Title: "My first post",
Text: "Happy me!",
Author: authorID,
Tags: []string{"new", "generation", "happy"},
Comments: []Comment{
{
Text: "Good to see you happy",
Creator: creatorID,
},
},
}
result, err := collection.InsertOne(ctx, post)
if err != nil {
log.Fatalf("Insert failed: %v", err)
}
fmt.Printf("Inserted post with ID: %v\n", result.InsertedID)
}
这个Go代码示例展示了:
- 使用Go结构体定义数据模型
- 使用
bson.M构建JSON Schema验证器 - 在创建集合时应用验证规则
- 正确插入符合验证规则的文档
验证失败通常是因为模式定义与插入数据不匹配。确保comments数组中的每个元素都是包含text(字符串)和creator(ObjectId)的对象,而不是直接使用ObjectId。

