英文:
sort a mongodb query based on a field in a subdocument in Go
问题
假设我有以下结构体:
type Test struct {
Title string `bson:"title" json:"title"`
Update Update `bson:"update" json:"update"`
}
type Update struct {
Changes []string `bson:"change" json:"change"`
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"`
}
假设我想按照 "update.updatedAt" 对查询结果进行排序:
cs.Find(bson.M{title: "some title"}).Sort("-update.updatedAt").Limit(10).All(&results)
这个查询不像预期的那样工作。我似乎找不到任何关于如何按子文档字段对查询进行排序的文档。直觉上,我确信我的示例会起作用。作为参考,"-updatedAt" 可以正常工作,但由于不必解释的原因,我必须将 Update 保持为 Test 的子文档。
到目前为止,我看到的每个示例和 Stack Overflow 的问题都涉及对子文档或数组进行排序和重新排序。在这种情况下,我不关心子文档的顺序,也不按数组内的任何内容排序。我只是想按子文档的日期对文档进行排序。
在 Go 的 Mgo Query 库中有没有办法做到这一点?
英文:
suppose I have the following struct
type Test struct {
Title string `bson:"title" json:"title"`
Update Update `bson:"update" json:"update"`
}
type Update struct {
Changes []string `bson:"change" json:"change"`
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"`
}
And suppose I want to sort my results in the Query by "update.updatedAt"
cs.Find(bson.M{title: "some title"}).Sort("-update.updatedAt").Limit(10).All(&results)
This query does not work as expected. I can't seem to find any documentation about how to sort a Query by a subdocument field. Intuitively, I was certain that my example would work. For reference, "-updatedAt" works just fine, but for reasons that aren't necessary to explain, I have to keep Update as a subdocument of Test.
Every example and Stack Overflow question I have seen so far involves the sorting and reordering of subdocuments, or arrays. In this case I don't care about the order of my subdocuments, and I'm not sorting by anything inside of an array. I merely want to sort my the documents by the date of a subdocument.
Is there a way to do this with the Go Mgo Query library?
答案1
得分: 2
我很确定问题出在你的数据结构上,因为下面的代码按预期工作(你可以在你的电脑上测试):
package main
import (
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"log"
"time"
)
type Test struct {
Title string `bson:"title" json:"title"`
Update Update `bson:"update" json:"update"`
}
type Update struct {
Changes []string `bson:"change" json:"change"`
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"`
}
func main() {
session, err := mgo.Dial("mongodb://souser:123456@ds055855.mlab.com:55855/catalog")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("catalog").C("sortable")
/*
// 填充测试数据到集合中(测试集合已经有15个元素)
for i := 0; i < 15; i++ {
c.Insert(&Test{
Title: "Title",
Update: Update{
Changes: []string{fmt.Sprintf("Changes #%d", i)},
UpdatedAt: time.Now(),
},
})
}
*/
var results []Test
err = c.Find(bson.M{"title": "Title"}).Sort("-update.updatedAt").Limit(10).All(&results)
if err != nil {
log.Fatal(err)
}
for _, e := range results {
fmt.Println(e.Update.UpdatedAt)
}
}
以上是你要翻译的内容。
英文:
I'm pretty sure it is something with your data structures because next code works as expected (you can test it on your PC)
package main
import (
"fmt"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"log"
"time"
)
type Test struct {
Title string `bson:"title" json:"title"`
Update Update `bson:"update" json:"update"`
}
type Update struct {
Changes []string `bson:"change" json:"change"`
UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"`
}
func main() {
session, err := mgo.Dial("mongodb://souser:123456@ds055855.mlab.com:55855/catalog")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("catalog").C("sortable")
/*
// Fill collection with test data (test collection aready has 15 elements)
for i := 0; i < 15; i++ {
c.Insert(&Test{
Title: "Title",
Update: Update{
Changes: []string{fmt.Sprintf("Changes #%d", i)},
UpdatedAt: time.Now(),
},
})
}
*/
var results []Test
err = c.Find(bson.M{"title": "Title"}).Sort("-update.updatedAt").Limit(10).All(&results)
if err != nil {
log.Fatal(err)
}
for _, e := range results {
fmt.Println(e.Update.UpdatedAt)
}
}
答案2
得分: 0
你需要以逗号(,)分隔的方式传递子文档字段,例如:
cs.Find(bson.M{title: "some title"}).Sort("update","-updatedAt").Limit(10).All(&results)
英文:
You need to pass subdocument fields comma(,) seperated like:
cs.Find(bson.M{title: "some title"}).Sort("update","-updatedAt").Limit(10).All(&results)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论