从MongoDB在Go API中过滤显示的信息。

huangapple go评论68阅读模式
英文:

Filtering what information is displayed from MongoDB in Go api

问题

我是Go和React的新手,我正在使用它们进行这个小项目。Go正在运行一个使用Mongodb的后端API。

我在Go中从Mongo中获取用户列表,然后将其发送到React,问题是Mongo给我返回了用户的所有字段(_id、password和username),我只想要username字段。我不明白如何过滤这些字段并阻止所有字段从Go发送到React。

Go API的JSON输出:

{
    "Success": true,
    "Data": [
        {
            "_id": "6205ac3d72c15c920a424608",
            "password": {
                "Subtype": 0,
                "Data": "removed for security"
            },
            "username": "removed for security"
        },
        {
            "_id": "6206b44afb8b044fdba76b8f",
            "password": {
                "Subtype": 0,
                "Data": "removed for security"
            },
            "username": "removed for security"
        }
    ]
}

这是我指定路由的Go代码:

// 路由:获取用户列表
func RouteGetUsers(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// 设置内容类型为JSON
	w.Header().Set("Content-Type", "application/json")

	type Response struct {
		Success bool     `json:"Success"`
		Data    []bson.M `json:"Data"`
	}

	// 加载环境变量文件
	err := godotenv.Load("variables.env")
	if err != nil {
		log.Fatal("加载.env文件时出错")
	}

	// 获取Mongo DB环境变量
	uri := os.Getenv("MONGO_URI")
	if uri == "" {
		log.Fatal("您必须设置您的'MONGO_URI'环境变量。请参阅\n\t https://docs.mongodb.com/drivers/go/current/usage-examples/#environment-variable")
	}

	// 连接到Mongo数据库
	client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
	if err != nil {
		panic(err)
	}

	// 在函数结束时关闭数据库连接
	defer func() {
		if err := client.Disconnect(context.TODO()); err != nil {
			panic(err)
		}
	}()

	// 选择数据库名称和集合名称
	coll := client.Database("go_project1").Collection("users")

	// 查询数据库获取用户列表
	cursor, err := coll.Find(context.TODO(), bson.D{})
	// 如果没有找到文档,则发送响应并返回
	if err == mongo.ErrNoDocuments {
		fmt.Printf("未找到文档")
		return
	}

	// 设置一个变量用于存储数据库结果
	var results []bson.M

	// 将所有数据库结果发送到results变量
	if err = cursor.All(context.TODO(), &results); err != nil {
		panic(err)
	}

	// 使用Response结构设置一个变量
	response := Response{
		Success: true,
		Data:    results,
	}

	// 转换为JSON
	responseJson, err := json.Marshal(response)
	if err != nil {
		fmt.Println(err)
	}

	// 以JSON格式向用户发送成功响应
	fmt.Fprintf(w, "%s\n", responseJson)
}
英文:

I am new to Go and React, both of which I am using for this mini project. Go is running a backend api using Mongodb.

I am fetching the user list from Mongo in Go, and then sending that to React, problem is Mongo is giving me all of the fields for the user (_id, password, and username), I only want username. I am not understanding how I can filter this and prevent all fields from being sent from Go to React.

JSON Output from Go API:

{
    "Success": true,
    "Data": [
        {
            "_id": "6205ac3d72c15c920a424608",
            "password": {
                "Subtype": 0,
                "Data": "removed for security"
            },
            "username": "removed for security"
        },
        {
            "_id": "6206b44afb8b044fdba76b8f",
            "password": {
                "Subtype": 0,
                "Data": "removed for security"
            },
            "username": "removed for security"
        }
    ]
}

Here is my Go code for the specified route:

// Route: Get Users, for getting a list of users
func RouteGetUsers(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	// Set content-type to JSON
	w.Header().Set("Content-Type", "application/json")

	type Response struct {
		Success bool     `json:"Success"`
		Data    []bson.M `json:"Data"`
	}

	// Load the env file
	err := godotenv.Load("variables.env")
	if err != nil {
		log.Fatal("Error loading .env file")
	}

	// Get Mongo DB environment variable
	uri := os.Getenv("MONGO_URI")
	if uri == "" {
		log.Fatal("You must set your 'MONGO_URI' environmental variable. See\n\t https://docs.mongodb.com/drivers/go/current/usage-examples/#environment-variable")
	}

	// Connect to Mongo Database
	client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
	if err != nil {
		panic(err)
	}

	// Close the database connection at the end of the function
	defer func() {
		if err := client.Disconnect(context.TODO()); err != nil {
			panic(err)
		}
	}()

	// Select the database name and collection name
	coll := client.Database("go_project1").Collection("users")

	// Query the database for the user list
	cursor, err := coll.Find(context.TODO(), bson.D{})
	// If no documents were found, send a response and return
	if err == mongo.ErrNoDocuments {
		fmt.Printf("No documents were found")
		return
	}

	// Setup a variable for the database results
	var results []bson.M

	// Send all database results to results variable
	if err = cursor.All(context.TODO(), &results); err != nil {
		panic(err)
	}

	// Setup a variable with the ResponseStandard struct
	response := Response{
		Success: true,
		Data:    results,
	}

	// Marshal into JSON
	responseJson, err := json.Marshal(response)
	if err != nil {
		fmt.Println(err)
	}

	// Send success response to user in JSON
	fmt.Fprintf(w, "%s\n", responseJson)
}

答案1

得分: 1

使用投影选项:

opts := options.Find().SetProjection(bson.D{{"username", 1}})
cursor, err := coll.Find(context.TODO(), bson.D{}, opts)

作为第二种方法:声明一个包含你想要的字段的类型,并将其提取到该类型中。

type Data struct {
   Username string `bson:"username" json:"username"`
}

...

var data []Data
if err = cursor.All(context.TODO(), &data); err != nil { ...

...

var response = struct {
    Success bool     `json:"Success"`
    Data    []Data   `json:"Data"`
}{
    true,
    data,
}
responseJson, err := json.Marshal(response)
...

第三种方法:过滤问题中的映射:

for _, result := range results {
    for k := range result {
       if k != "username" {
          delete(result, k)
       }
    }
}
英文:

Use the projection option:

opts := options.Find().SetProjection(bson.D{{"username", 1}})
cursor, err := coll.Find(context.TODO(), bson.D{}, opts)

As second approach: Declare a type with the fields you want, and fetch to that type.

type Data struct {
   Username string `bson:"username" json:"username"`
}

...

var data []Data
if err = cursor.All(context.TODO(), &data); err != nil { ...

...

var response = struct {
    Success bool     `json:"Success"`
    Data    []Data   `json:"Data"`
}{
    true,
    data,
}
responseJson, err := json.Marshal(response)
...

A third approach: Filter the maps in the question:

for _, result := range results {
    for k := range result {
       if k != "username" {
          delete(result, k)
       }
    }
}

huangapple
  • 本文由 发表于 2022年2月19日 02:55:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/71178546.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定