Reputation: 77
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
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
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