dth2331 2016-05-20 11:11
浏览 60
已采纳

如何在mgo中对数组元素进行多级拉取?

I want to do a multi-level array element delete. My Structs are as follows:-

type Company struct {
    Id              bson.ObjectId `bson:"_id,omitempty"`
    CompanyName     string
    Process         []ProcessItem
}

type ProcessItem  struct{
    SortOrder       int
    Documents       []DocumentTemplate
}

type DocumentTemplate struct {
    Id              bson.ObjectId `bson:"_id,omitempty"`
    TemplateName    string
}

I want to delete an object of type DocumentTemplate. The DocumentTemplate is a struct array in ProcessItem which is a struct array in Company struct. I have Company Id(field of struct Company) and TemplateName(field of struct DocumentTemplate).

I tried the below mgo pull query but it is not working.

c := db.C("company")
pullQuery := bson.M{"process": bson.M{"documents.templatename": "xyz"}}
err := c.Update(bson.M{"_id": "123"}, bson.M{"$pull": pullQuery})

Please point out the mistakes I made here. Thanks.

Edit: Adding one example document for the clarity of the question

{
    "_id" : ObjectId("573da7dddd73171e42a84045"),
    "companyname" : "AAA",
    "process" : [ 
        {
            "processname" : "Enquiry",
            "sortorder" : 0,
            "documents" : [ 
                {
                    "templatename" : "xyz",
                    "processname" : "Enquiry"
                }, 
                {
                    "templatename" : "ss",
                    "processname" : "Enquiry"
                }
            ]
        }, 
        {
            "processname" : "Converted",
            "processtype" : 1,
            "sortorder" : 2,
            "documents" : [ 
                {
                    "templatename" : "dd",
                    "processname" : "Converted"
                }, 
                {
                    "templatename" : "fg",
                    "processname" : "Converted"
                }
            ]
        }
    ]
}

I need to pull out just one DocumentTemplete record, like the one below:

{
   "templatename" : "xyz",
   "processname" : "Enquiry"
}

N.B: TemplateName will be unique inside a Company.

  • 写回答

2条回答 默认 最新

  • duanliang1898 2016-05-20 12:10
    关注

    You'll need to use the $ positional operator (https://docs.mongodb.com/manual/reference/operator/projection/positional/). In order to be able to use that you'll also have to add to your query the following:

    "process.documents.templatename": "xyz"
    

    Your Update statement should look like this:

    c := db.C("company")
    pullQuery := bson.M{"process.$.documents": bson.M{"templatename": "xyz"}}
    err := c.Update(bson.M{"_id": "123", "process.documents.templatename": "xyz"}, bson.M{"$pull": pullQuery})
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵