看到 Go 与 MongoDB 的交互方式,我想放弃 Go 了

2021-10-24 11:48:43 +08:00
balabalaguguji  balabalaguguji

之前习惯了 python/js 这种语法,感觉很自然很方便。

今天看了下 MongoDB 官方的 Go 接口,哎呀,那交互方式,真的是痛苦。

例如查询用户为 1 的用户:{userid: 1},在 Go 里面你还得包裹为 bson.D{{"userid", 1}}

返回的结果是一个索引,要 Decode 下,Docode 还需要传递一个结构体过去。

还得传递一个 context (还没看为啥要这么做,其他语言不用)

感觉一点也不方便,代码很多不美观不优雅,习惯了 js/python 这种比较简单直观的语法,难以接受呀。

感觉 Google 最近出的东西,语法都那么特立独行的,还有一个是死亡嵌套 Flutter ,嵌套到怀疑人生。

官方教程: https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial

filter := bson.D{{"name", "Ash"}}

update := bson.D{
    {"$inc", bson.D{
        {"age", 1},
    }},
}

updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)
14560 次点击
所在节点   Go 编程语言  Go 编程语言
99 条回复
linhongye
linhongye
2021-10-24 15:14:47 +08:00
我们就是 Go+mongo, 舒服得很...
搞点插件熟练一下...
balabalaguguji
balabalaguguji
2021-10-24 15:24:56 +08:00
@linhongye #21 怎么会舒服,具体点怎么搞
balabalaguguji
balabalaguguji
2021-10-24 15:30:20 +08:00
@Weny #20 感觉还是很复杂麻烦?
用你这个封装好的代码写一个查询用户 ID=1 的怎么查?
复杂点的 aggregate 怎么写,如下:
pipline = [
{'$match': {'taskId': {'$in': taskIds}}},
{'$lookup': {"from": "groupLogs", "localField": "groupId", "foreignField": "_id", "as": "groupData"}},
{'$match': {'groupData': {'$size': 1}}},
{'$group': {'_id': '$taskId', 'count': {'$sum': '$totalCount'}}},
]
40EaE5uJO3Xt1VVa
40EaE5uJO3Xt1VVa
2021-10-24 15:32:08 +08:00
@linhongye 怎么搞的请教一下
jim9606
jim9606
2021-10-24 16:18:28 +08:00
你说的问题其实是强类型语言的问题,如果你对程序鲁棒性要求要一些,要对所有输入做格式和类型校验,那不可能优雅的。
go 里面任意类型的 map 是 map[string]interface{},不过访问这玩意的代码写起来也很烦就是了。
clf
clf
2021-10-24 16:26:09 +08:00
java 的 mongo template 其实也是构建一个 Document 丢进去查询,mongo 官方基本就提供了连接和调用查询的基本方式,更多的还是由 orm 框架实现。
learningman
learningman
2021-10-24 16:26:14 +08:00
go 处理 json 就是不爽啊,想爽用 js
holulu
holulu
2021-10-24 16:37:51 +08:00
强类型都有这种问题,用过的语言多了,不同范畴的代码都写过了,就会看淡了。语言就是个工具,没必要看得那么重,大不了就换。
xnotepad
xnotepad
2021-10-24 16:52:05 +08:00
这应该是所有静态语言都有的问题。
Weny
Weny
2021-10-24 17:16:00 +08:00
@balabalaguguji 其实本质上就是一个 Map 的 builder

第一个问题 :queryBuilder.Where("user_id",id)

aggregate 我觉得再封装一个 pipeline builder ,再扩展一下已有的 queryBuilder 比如
pipelineBuilder(
queryBuilder.Match("taskId",func(q){return q.in(taskIds)}),
queryBuilder.Lookup(func(q){return q.Form("")...})
...
)
gengchun
2021-10-24 17:25:48 +08:00
要静态语言,要性能就是这个结果。

可以找一些 orm ,我记得有的不需要传 context ;当然 orm 又会有性能问题,你对 orm 的一些选择也未必会满意。
xuanbg
2021-10-24 17:48:12 +08:00
自己再封装一下啊
TypeError
2021-10-24 18:17:44 +08:00
qmgo
xsen
2021-10-24 19:20:54 +08:00
这跟语言有什么关系,这只是 mongodb 的 sdk 没有封装好而已
都有参考的理想的用法,那自己再封装一层不就是可以

对于 flutter 嵌套这样的,对原有做 pc 客户端的(如 c++)的就很是友好
只是一个思维习惯的问题
zxCoder
2021-10-24 19:33:47 +08:00
感觉 mongodb 还是适合 js/ts
sunmoon1983
2021-10-24 19:36:27 +08:00
七牛的 qmgo
fireleaves
2021-10-24 19:50:27 +08:00
@balabalaguguji 试试这样一个 pipline 转 bson 接口呢?

```golang
// MongoPipeline gets aggregation pipeline from a string
func MongoPipeline(str string) mongo.Pipeline {
var pipeline = []bson.D{}
str = strings.TrimSpace(str)
if strings.Index(str, "[") != 0 {
var doc bson.D
bson.UnmarshalExtJSON([]byte(str), false, &doc)
pipeline = append(pipeline, doc)
} else {
bson.UnmarshalExtJSON([]byte(str), false, &pipeline)
}
return pipeline
}
```

这样调用

```golang
pipline = `pipline = [
{'$match': {'taskId': {'$in': taskIds}}},
{'$lookup': {"from": "groupLogs", "localField": "groupId", "foreignField": "_id", "as": "groupData"}},
{'$match': {'groupData': {'$size': 1}}},
{'$group': {'_id': '$taskId', 'count': {'$sum': '$totalCount'}}},
]`
opts := options.Aggregate()
if res, err = collection.Aggregate(ctx, MongoPipeline(pipeline), opts); err != nil {
t.Fatal(err)
}
```

参考自: https://github.com/simagix/mongo-go-examples
Fitz
2021-10-24 20:54:56 +08:00
静态语言不都这样吗 无非是怎么封装,context 是为了并发控制, 这个没什么好喷的, 你只是没遇到需要它的场景
balabalaguguji
2021-10-24 20:58:44 +08:00
@jim9606 #25 是这么回事,强类型的都得这么麻烦。
balabalaguguji
2021-10-24 21:01:18 +08:00
@clf #26 看了下 Java 的,构建一个 Document 感觉比 Go 这种方式好很多,好接受多了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/810126

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX