Golang,无法执行mongodb的select操作。

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

Golang , mongodb can not do select

问题

在我的情况下,我有一个集合,其中存储了以下结构的数据:

{ 
    "_id" : ObjectId("59ad187a0447d3617fb802b8"), 
    "fid" : ObjectId("59ad187a6b9600120bd03a53"), 
    "pr" : [
        {
            "_id" : ObjectId("59ad187a6b9600120bd03a53"), 
            "trashed" : false
        }
    ], 
    "ch" : [
        {
            "_id" : ObjectId("59ad18a36b9600120bd03a57"), 
            "trashed" : false
        }, 
        {
            "_id" : ObjectId("59ad18a36b9600120bd03a99"), 
            "trashed" : false
        }, 
        {
            "_id" : ObjectId("59ad18a36b9600120bd03a98"), 
            "trashed" : true
        }, 
        {
            "_id" : ObjectId("59ad18a36b9600120bd03a97"), 
            "trashed" : false
        }
    ]
}

所以我想获取chtrashedfalse的所有对象。

这是我的查询代码:

type ChildParentsData struct {
    Id      bson.ObjectId `json:"_id,omitempty" bson:"_id,omitempty"`
    Trashed bool          `json:"trashed" bson:"trashed"`
}

var tree []ChildParentsData
err := Connection.Session.DB("cctv_storage").C("tree").Find(
    bson.M{
        "fid": bson.ObjectIdHex(id), "ch.trashed": false
    }).Select(
    bson.M{
        "ch.$": 1
    }).All(&tree)

但是作为响应,我得到了所有的数据,但我只需要ch中的objects

英文:

In my case I have a collection where I have stored a data with a structure that below

{ 
    "_id" : ObjectId("59ad187a0447d3617fb802b8"), 
    "fid" : ObjectId("59ad187a6b9600120bd03a53"), 
    "pr" : [
        {
            "_id" : ObjectId("59ad187a6b9600120bd03a53"), 
            "trashed" : false
        }
    ], 
    "ch" : [
        {
            "_id" : ObjectId("59ad18a36b9600120bd03a57"), 
            "trashed" : false
        }, 
        {
            "_id" : ObjectId("59ad18a36b9600120bd03a99"), 
            "trashed" : false
        }, 
        {
            "_id" : ObjectId("59ad18a36b9600120bd03a98"), 
            "trashed" : true
        }, 
        {
            "_id" : ObjectId("59ad18a36b9600120bd03a97"), 
            "trashed" : false
        }
    ]
}

So I want to get all objects in ch where trashed is false

Here is my query

       type ChildParentsData struct {
       Id      bson.ObjectId `json:"_id,omitempty" bson:"_id,omitempty"`
       Trashed bool          `json:"trashed" bson:"trashed"`
       }
        var tree []ChildParentsData
        err := Connection.Session.DB("cctv_storage").C("tree").Find(
               bson.M{
                  "fid": bson.ObjectIdHex(id), "ch.trashed": false
               }).Select(
               bson.M{
                  "ch.$": 1
                }).All(&tree)

But as a response I am getting all data, but I need only objects in ch

答案1

得分: 2

您可以使用聚合框架来实现这一点,感谢在MongoDB 3.4中引入的**$replaceRoot**操作符。

首先,我们获取特定fid的匹配文档,然后展开数组并删除ch.trashed为true的文档。最后,我们通过将ch的内容提升为文档的根来删除ch字段。

以下是实现此目的的代码:

type ChildParentsData struct {
    Id      bson.ObjectId `json:"_id,omitempty" bson:"_id,omitempty"`
    Trashed bool          `json:"trashed" bson:"trashed"`
}
var tree []ChildParentsData

pipeline := []bson.M{
    {"$match": bson.M{"fid": bson.ObjectIdHex("59ad187a6b9600120bd03a53")}},
    {"$unwind": "$ch"},
    {"$match": bson.M{"ch.trashed": false}},
    {"$replaceRoot": bson.M{"newRoot": "$ch"}}}

err = Connection.Session.DB("cctv_storage").C("tree").Pipe(pipeline).All(&tree)

if err != nil {
    fmt.Printf("error: %v", err)
    os.Exit(0)
}
fmt.Printf("doc: %v", tree)

希望对您有所帮助!

英文:

You can achieve this using the aggregation framework, thanks to the $replaceRoot operator introduced in MongoDB 3.4

We first get matching documents for the specific fid, then we unwind the array and remove docmuments where ch.trashed is true. Finally, we remove the ch field by promoting the content of ch as root of the document

Here is the code to achieve this:

type ChildParentsData struct {
		Id      bson.ObjectId `json:"_id,omitempty" bson:"_id,omitempty"`
		Trashed bool          `json:"trashed" bson:"trashed"`
}
var tree []ChildParentsData

pipeline := []bson.M{
	{"$match": bson.M{"fid": bson.ObjectIdHex("59ad187a6b9600120bd03a53")}},
	{"$unwind": "$ch"},
	{"$match": bson.M{"ch.trashed": false}},
	{"$replaceRoot": bson.M{"newRoot": "$ch"}}}

err = Connection.Session.DB("cctv_storage").C("tree").Pipe(pipeline).All(&tree)

if err != nil {
	fmt.Printf("error: %v", err)
	os.Exit(0)
}
fmt.Printf("doc: %v", tree)

答案2

得分: 0

获取特定字段而不是所有字段的一种快速方法是使用投影。以下是一个使用golang的示例:

    filter := bson.D{{" _id ",bson.ObjectIdHex(" 59ad187a6b9600120bd03a53 ")}}
    projection := bson.D{{" ch ",0}}
    collection.FindOne(context.TODO(),filter,options.FindOne())
英文:

An quick way to get the particular fields instead of all the fileds is using projection. An example of golang is here:

    filter := bson.D{{"_id" , bson.ObjectIdHex("59ad187a6b9600120bd03a53")}}
    projection := bson.D{{"ch", 0}}
    collection.FindOne(context.TODO(), filter, options.FindOne())

huangapple
  • 本文由 发表于 2017年9月4日 19:21:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/46035952.html
匿名

发表评论

匿名网友

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

确定