Как сделать многоуровневое извлечение элемента массива в mgo?

Я хочу удалить элемент многоуровневого массива. Мои структуры следующие: -

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
}

Я хочу удалить объект типа DocumentTemplate. DocumentTemplate — это массив структур в ProcessItem, который является массивом структур в структуре Company. У меня есть идентификатор компании (поле структуры Company) и TemplateName (поле структуры DocumentTemplate).

Я попробовал приведенный ниже запрос mgo pull, но он не работает.

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

Пожалуйста, укажите на ошибки, которые я сделал здесь. Спасибо.

Изменить: добавление одного примера документа для ясности вопроса.

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

Мне нужно вытащить только одну запись DocumentTemplete, как показано ниже:

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

N.B: TemplateName будет уникальным внутри компании.


person Arjun Ajith    schedule 20.05.2016    source источник
comment
Является ли TemplateName уникальным, или один объект Company может содержать множество DocumentTemplate с одним и тем же именем, и если да, хотите ли вы получить каждый из них?   -  person John Smith    schedule 20.05.2016
comment
Имена шаблонов @JohnSmith будут уникальными. Я добавил подтверждение для этого. Для каждой компании будет только одно имя шаблона xyz. Пожалуйста, проверьте мое редактирование в вопросе. Спасибо   -  person Arjun Ajith    schedule 20.05.2016


Ответы (2)


Вам нужно будет использовать позиционный оператор $ (https://docs.mongodb.com/manual/reference/operator/projection/positional/). Чтобы иметь возможность использовать это, вам также необходимо добавить в свой запрос следующее:

"process.documents.templatename": "xyz"

Ваше заявление Update должно выглядеть так:

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})
person John Smith    schedule 20.05.2016

Вы можете вытащить значения в массиве из массива в записи монго

 change2 := bson.M{
                "$pull": bson.M{"sapinfo.systemstatus": bson.M{"$in": tags}},
            }
person Sandun Priyanka    schedule 14.03.2018