mongodb - 如何执行仅获取第一个元素的查找
问题描述
我有这两个结构:
Category struct {
ID primitive.ObjectID `bson:"_id"`
Name string `bson:"name"`
}
Book struct {
ID primitive.ObjectID `bson:"_id"`
Name string `bson:"name"`
Category *Category `bson:"category"`
}
我想找到一本汇总其类别的书并执行此查询
// lookup stage
lookupStage := bson.D{{"$lookup", bson.D{
{"from", "category"},
{"localField", "category"},
{"foreignField", "_id"},
{"as", "category"}}}}
通过此查找,我会将获取的类别文档放入图书的类别字段中。
// match stage (cut for simplicity, it doesn't care)
var matchStage bson.D = ...
pipeline := mongo.Pipeline{
matchStage,
lookupStage,
}
cur, err := bookCollection.Aggregate(context.TODO(), pipeline)
cur.Decode(&book)
如果我直接在 MongoDB 中执行查询一切正常,但在 Go 中我得到一个空类别。我认为问题在于查找返回一个数组但我试图将它映射到一个对象上。
所以问题是:如何获取查找操作产生的数组的第一个元素并将其放置在 book 实例中?
我正在使用 mongo 官方驱动程序。
解决方案
如果我直接在 MongoDB 中执行查询一切正常,但在 Go 中我得到一个空类别。我认为问题在于查找返回一个数组但我试图将它映射到一个对象上。
$lookup阶段确实返回一个数组,但如果这是您的问题,您可能会收到一个错误,例如cannot decode array into a Category
. 它可能是由其他原因引起的,下面的答案将显示一个工作示例,希望也能帮助您解决问题。
这里有两种选择,具体取决于您的用例。首先是声明Category
为数组,即
type Book struct {
ID primitive.ObjectID `bson:"_id"`
Name string `bson:"name"`
Category []*Category `bson:"category"`
}
其次,您可以利用$unwind阶段来删除阵列。例如:
collection := client.Database("go").Collection("book")
lookupStage := bson.D{{"$lookup", bson.D{
{"from", "category"},
{"localField", "category"},
{"foreignField", "_id"},
{"as", "category"}}}}
unwindStage := bson.D{{"$unwind", "$category"}}
pipeline := mongo.Pipeline{lookupStage, unwindStage}
cursor, err := collection.Aggregate(context.TODO(), pipeline)
defer cursor.Close(context.TODO())
if err != nil {
panic(err)
}
cursor.Next(context.TODO())
var book Book
err = cursor.Decode(&book)
if err != nil {
panic(err)
}
fmt.Println(book)
说了以上所有内容,根据您的用例,您应该重新考虑架构。假设图书类别不会经常更改,您可以将其嵌入Category
到Book
. 这将简化很多查询,因为图书类别可能是图书的重要信息。
有关模式设计的更多信息,请参阅使用模式构建:摘要
推荐阅读
- android - 进程 'command'/Users/rodrigovieira/Library/Android/sdk/ndk-bundle/ndk-build'' 以非零退出值 2 结束
- c++ - CGAL 将非流形 Nef_polyhedron_3 转换为三角形网格
- apache-spark - 如何在pyspark中读取多级json?
- jenkins - 没有这样的属性:类的 scm: Jenkins 版本中的 groovy.lang.Binding。2.107.2。
- python - 如何获取具有多个打印语句的 API 调用函数以在 Flask 中显示?
- sql-server - 基于连接字符串/环境的 SSMS 颜色选项卡
- android - 在 Android Auto Queue 中选择媒体项不执行任何操作
- php - Nginx:将子域重写到其中的文件夹和文件
- python - 如何将 Celery 任务从一台机器发送到另一台机器?
- webrtc - 边缘回声 webrtc