Khazar Amjer
Khazar Amjer

Reputation: 77

Golang , mongodb can not do select

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

Upvotes: 2

Views: 734

Answers (2)

yzark
yzark

Reputation: 131

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())

Upvotes: 0

felix
felix

Reputation: 9285

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)

Upvotes: 2

Related Questions