Golang,MongoDB的不能做选择

问题描述:

在我来说,我有我在那里存储着数据与下面Golang,MongoDB的不能做选择

{ 
    "_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 
     } 
    ] 
} 

所以我想在ch的所有对象,其中丢弃是false

结构的集合

这里是我的查询

 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) 

但作为一个响应我收到的所有数据,但我只objects需要ch

+0

'Find'返回符合条件的整个文档。在你的情况下,条件是:'fid'等于某个'id','ch'至少有一个'trashed'的子文档等于'false'。您需要在客户端处理结果,或者使用[聚合框架](https://godoc.org/labix.org/v2/mgo#Collection.Pipe)。 –

+0

预期结果是什么?一个包含'trashed'的所有'ch'项的大数组是否为false?有几个过滤了'ch'数组的文件?你应该发布'ChildParentsData'结构来使其更清晰 – felix

+0

谢谢@felix,我已经添加了结构 –

为此,可以使用的聚合框架,得益于MongoDB的3.4

推出$replaceRoot运营商实现我们首先得到匹配的文档的具体fid,那么我们放松的阵列,并删除docmuments其中ch.trashed是真的。最后,我们通过促进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)