我正在尝试将类型转换primitive.ObjectID
为string
Go 中的类型。我正在使用mongo-driver
from go.mongodb.org/mongo-driver
.
我尝试使用类型断言
mongoId := mongoDoc["_id"];
stringObjectID := mongoId.(string)
Run Code Online (Sandbox Code Playgroud)
哪个 VSCode 接受。代码被编译,当它到达这个特定的代码行时,它会抛出这个错误
panic: interface conversion: interface {} is primitive.ObjectID, not string
Run Code Online (Sandbox Code Playgroud) 我正在与https://github.com/mongodb/mongo-go-driver 合作,目前正在尝试实现此类结构的部分更新
type NoteUpdate struct {
ID string `json:"id,omitempty" bson:"_id,omitempty"`
Title string `json:"title" bson:"title,omitempty"`
Content string `json:"content" bson:"content,omitempty"`
ChangedAt int64 `json:"changed_at" bson:"changed_at"`
}
Run Code Online (Sandbox Code Playgroud)
例如,如果我有
noteUpdate := NoteUpdate{ Title: "New Title" }
Run Code Online (Sandbox Code Playgroud)
然后我希望存储文档中唯一的“标题”字段将被更改。
我需要写一些类似的东西
collection.FindOneAndUpdate(context.Background(),
bson.NewDocument(bson.EC.String("_id", noteUpdate.ID)),
// I need to encode non-empty fields here
bson.NewDocument(bson.EC.SubDocument("$set", bson.NewDocument(...)))
)
Run Code Online (Sandbox Code Playgroud)
问题是我不想用bson.EC.String(...)
or手动编码每个非空字段bson.EC.Int64(...)
。我尝试使用bson.EC.InterfaceErr(...)
但出现错误
无法为 *models.NoteUpdate 类型创建元素,请尝试使用 bsoncodec.ConstructElementErr
不幸的是,bsoncodec 中没有这样的功能。我发现的唯一方法是创建包装器
type SetWrapper struct {
Set interface{} `bson:"$set,omitempty"`
}
Run Code Online (Sandbox Code Playgroud)
并使用它
partialUpdate := &NoteUpdate{
ID: "some-note-id",
Title: "Some new title", …
Run Code Online (Sandbox Code Playgroud) 当我使用新的MongoDB Go驱动程序插入到一个集合中时,我得到一个重复的异常,我可以在喷出它时看到它。 (mongo.WriteException)
多个写入错误:
[{写入错误:[{E11000重复键错误集合:fhir.documents索引:enterprise_id_1 dup key:{:“Cache-37”,:“102”}}]},{}]
我如何获得内部错误以编程方式知道它是一个重复的密钥并且我可以处理它?
这个特定问题与将 mongodb 与 golang 包一起使用有关mongo-driver
,但我认为这适用于大多数与 mongodb 的接口。
当Find
用于从集合中查询某些数据时,我们可以同时使用bson.M
- 和bson.D
- 类型来指定此查找的过滤器。
bson.D
如果元素的顺序很重要,bson.M
则应根据文档使用,否则应使用。
D 是 BSON 文档的有序表示。当元素的顺序很重要时,应该使用这种类型,例如 MongoDB 命令文档。如果元素的顺序无关紧要,则应使用 M 代替。
现在我的问题是使用这些结构中的任何一个,即有序与无序,结构是否会对 mongo 查询优化器生成的查询计划产生影响。
在经典的 SQL 数据库中,顺序通常无关紧要,因为优化器足够聪明,可以使用汇总统计信息、索引等来确定首先执行哪些查询。
我是否可以假设这里也是这种情况,或者使用有序结构来查询我的集合是否会以某种方式干扰这一点/是否使用类似于使用优化器提示的有序结构工作?如果有一些干扰,这是否受到要搜索的字段是否被索引的影响?
我无法让官方 go mongo 驱动程序成功返回通过正则表达式查询查询的对象。
我已经知道如何通过 mongo shell 进行操作并获得预期的结果。在这个例子中,我得到了所有在“文本”字段中包含“他”的条目:
db.getCollection('test').find({"text": /he/})
Run Code Online (Sandbox Code Playgroud)
与此相同:
db.getCollection('test').find({"text": {$regex: /he/, $options: ''}})
Run Code Online (Sandbox Code Playgroud)
这是我当前不起作用的代码:
package main
import (
"context"
"fmt"
"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"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(5*time.Second))
defer cancel()
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
if err != nil {
fmt.Println(err)
return
}
err = client.Connect(ctx)
if err != nil {
fmt.Println(err)
return
}
db := client.Database("test")
coll := db.Collection("test")
filter := bson.D{{"text", primitive.Regex{Pattern: "/he/", Options: ""}}}
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) …
Run Code Online (Sandbox Code Playgroud) 我正在从 MongoDB 获取文档并将其传递给函数transform
,例如
var doc map[string]interface{}
err := collection.FindOne(context.TODO(), filter).Decode(&doc)
result := transform(doc)
Run Code Online (Sandbox Code Playgroud)
我想为 编写单元测试transform
,但我不确定如何模拟来自 MongoDB 的响应。理想情况下我想设置这样的东西:
func TestTransform(t *testing.T) {
byt := []byte(`
{"hello": "world",
"message": "apple"}
`)
var doc map[string]interface{}
>>> Some method here to Decode byt into doc like the code above <<<
out := transform(doc)
expected := ...
if diff := deep.Equal(expected, out); diff != nil {
t.Error(diff)
}
}
Run Code Online (Sandbox Code Playgroud)
一种方法是json.Unmarshal
into doc
,但这有时会产生不同的结果。例如,如果 MongoDB 中的文档中有一个数组,那么该数组将被解码为doc
类型bson.A
而不是[]interface{} …
我想知道是否有任何方法可以让我在将 MongoDB 文档解组为 Go 结构时忽略空类型。
现在我有一些自动生成的 Go 结构,如下所示:
type User struct {
Name string `bson:"name"`
Email string `bson:"email"`
}
Run Code Online (Sandbox Code Playgroud)
更改此结构中声明的类型不是一个选项,问题就在这里;在我无法完全控制的 MongoDB 数据库中,某些文档已插入空值,而最初我并不期待空值。像这样的东西:
{
"name": "John Doe",
"email": null
}
Run Code Online (Sandbox Code Playgroud)
由于在我的结构中声明的字符串类型不是指针,它们无法接收nil
值,因此每当我尝试在我的结构中解组此文档时,它都会返回错误。
防止将此类文档插入数据库将是理想的解决方案,但对于我的用例,忽略空值也是可以接受的。因此,在解组文档后,我的 User 实例将如下所示
{
"name": "John Doe",
"email": null
}
Run Code Online (Sandbox Code Playgroud)
我试图找到一些注释标志,或者可以传递给方法Find
/的选项FindOne
,或者甚至是一个查询参数,以防止从数据库中返回任何包含空值的字段。直到现在都没有任何成功。
mongo-go-driver 中是否有针对此问题的内置解决方案?
我正在集合中插入新项目。为此使用官方 mongo go 驱动程序(https://github.com/mongodb/mongo-go-driver)。
collection.InsertOne(context.Background(), map[string]interface{}{
"string": "test",
"integer": 123,
"float": 0.123,
"array": []string{"t", "e", "s", "t"},
"objectid": objectid.New(),
"time": time.Now(),
})
Run Code Online (Sandbox Code Playgroud)
但结果我有几个属性的问题:time.Time 和 objectid.ObjectID。
我知道它只是处于 alpha 状态,但也许有人知道。是我做错了还是没有按照应有的方式实施?
我正在从 mgo 驱动程序迁移,我的函数如下所示:
queue := collection.Bulk()
for j := range changes {
..
queue.Update(doc, update)
}
saveResult, err := queue.Run()
Run Code Online (Sandbox Code Playgroud)
这会在循环中对单个文档进行一些$push
和$set
更新。我应该如何使用官方驱动程序执行此操作?是collection.BulkWrite()
还是collection.UpdateMany()
?文档太模糊了,我不知道如何使用它们以及有什么区别。任何帮助,将不胜感激。
我在 graphql 中与 Mongo go 驱动程序有这种一对多的引用关系。
type User {
id: ObjectID!
email: String!
username: String!
posts: [Post!]!
}
type Post {
id: ObjectID!
author: User!
title: String!
content: String!
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用Aggregate框架来查询引用关系。
但是,如果我想创建用户同时也创建帖子怎么办?
collection.InsertOne
在解析器中发送两个?