jeudi 26 novembre 2015

Mongodb Pipeline Unset (Delete document from array)

I have a mgo pipeline in Go that inserts a unit object inside a floor object inside a building object that like this (Building > Floor > Unit):

The full Struct Layout can be found here > http://ift.tt/21iCJsF

Here is my unit insertion, for example:

func InsertUnit(database *mgo.Database, bldg_uuid string, floor_uuid string, unit_number string) error {

    calc_unit_uuid := tmp_crypt_b(bldg_uuid + floor_uuid + unit_number)

    pipeline := []bson.M{
        {"$match": bson.M{"b": bldg_uuid}},
        {"$unwind": "$p"},
        {"$unwind": "$p.u"},
        {"$match": bson.M{
            "p.f":    floor_uuid,
            "p.u.uu": calc_unit_uuid,
        }},
    }

    var resp map[string]interface{}
    database.C("buildings").Pipe(pipeline).One(&resp)

    fmt.Println(resp)

    if resp == nil {

        pipeline := []bson.M{
            {"$match": bson.M{"b": bldg_uuid}},
            {"$unwind": "$p"},
            {"$match": bson.M{
                "p.f": floor_uuid,
            }},
        }

        var resp map[string]interface{}
        database.C("buildings").Pipe(pipeline).One(&resp)

        if resp != nil {

            init_unit := Unit{
                UnitUUID:   calc_unit_uuid,
                BldgUUID:   bldg_uuid,
                FloorUUID:  floor_uuid,
                UnitNumber: unit_number,
            }

            init_unit.ID = bson.NewObjectId()

            fmt.Println("Insert Unit Success")

            return database.C("buildings").Update(
                bson.M{"b": bldg_uuid, "p.f": floor_uuid},
                bson.M{
                    "$push": bson.M{"p.$.u": init_unit},
                },
            )

        } else {
            fmt.Println("No such building or floor")
        }
    } else {
        fmt.Println("Unit Already Exist")
    }

    return errors.New("x")

}

How would I approach Deletion using a similar pipeline that possibly involves using $unset? I have tried many ways but so far I'm without luck. One of my attempts for example:

        pipeline := []bson.M{
            {"$match": bson.M{"b": bldg_uuid}},
            {"$unwind": "$p"},
            {"$match": bson.M{
                "p.u.uu": calc_unit_uuid,
            }},
            {"$unset": "$p.u.$"},
        }

        database.C("buildings").Pipe(pipeline)

I tried deleting $p.u.$, which I think $ equals what $match finds. The query apparently did nothing and the Unit remains still where it was.

If there is a better way of removing the Unit, with or without using pipelines, I'd replace mine with it any day!

Thanks!

Aucun commentaire:

Enregistrer un commentaire