Search code examples
mongodbdictionarygobsonmgo

Getting error while deleting the key value from array of objects


I am getting the following error while deleting from key from array of JSON objects using Go. Error:

    repository/orderRepository.go:394:11: first argument to delete must be map; have interface {}
    repository/orderRepository.go:395:11: first argument to delete must be map; have interface {}
    repository/orderRepository.go:396:11: first argument to delete must be map; have interface {}
    repository/orderRepository.go:397:11: first argument to delete must be map; have interface {}
    repository/orderRepository.go:398:11: first argument to delete must be map; have interface {}

I am explaining my code below.

    func SyncOrders() map[string]interface{} {
        logger.Log.Println("OrderRepository SyncOrders Begin")
        resourceManager := resources.ResourceManager{}
        session, error := driver.Connect()
        db := session.DB(config.Configuration.Database)
        var resp map[string]interface{}

        if error != nil {
            resp := utils.Message(resourceManager.GetProperty(constants.ERROR), resourceManager.GetProperty(constants.DB_SERVER_NOT_REACHABLE_CODE), resourceManager.GetProperty(constants.DB_SERVER_NOT_REACHABLE_DESC))
            return resp
        } else {
            var result []interface{}
            //filter := bson.M{"Customer.CustomerID": id, "PaymentDetails.PaymentStatus": "Payment Received"}
            //fmt.Println(filter)
            err := db.C(ORDERCOLLECTION).Find(nil).All(&result)
            if err == nil {
                resp = utils.Message(resourceManager.GetProperty(constants.SUCCESS), resourceManager.GetProperty(constants.PRODUCT_GETBYID_CODE), resourceManager.GetProperty(constants.PRODUCT_GETBYID_DESC))
                for i := 1; i < len(result); i++ {

                    delete(result[i],"_id");
                    delete(result[i],"CreatedAt");
                    delete(result[i],"CreatedBy");
                    delete(result[i],"UpdatedAt");
                    delete(result[i],"UpdatedBy");
                }
                resp["data"] = result
            } else {
                //fmt.Println(err)
                resp = utils.Message(resourceManager.GetProperty(constants.ERROR), resourceManager.GetProperty(constants.PRODUCT_GETBYID_NOTFOUND_CODE), resourceManager.GetProperty(constants.PRODUCT_GETBYID_NOTFOUND_DESC))
            }
            defer session.Close()
            return resp
        }
    }

Here I am fetching some record from MongoDB and delete some key value from each record but when I am running the server I am getting these errors. As I am beginner to Go. Can anybody help me to resolve these errors?


Solution

  • The error message says it all: the first argument to the builtin delete() must be a value of static type map.

    Your result variable is of type []interface{}, so indexing it like result[i] will result in a value of type interface{}.

    If it holds a map, you may use type assertion to obtain the map value from it. Since you use the mgo driver, it is of type bson.M (which is a map[string]interface{}), so you may do it like this:

    delete(result[i].(bson.M), "_id")
    

    But it would be better if you would declare result to be a slice of maps in the first place:

    var result []bson.M
    

    So then no type assertion will be needed, and the following will be valid code:

    delete(result[i], "_id")
    

    Also note that if you want to remove these properties from the results, it would be best if you would tell MongoDB you don't need these fields and so the server wouldn't even send these (saving network traffic) and then you wouldn't have to remove them (saving time and memory).

    Use projection to tell you don't need these fields. In mgo you can set a projection using the Query.Select() method.

    For example:

    err := db.C(ORDERCOLLECTION).Find(nil).Select(bson.M{
        "_id":       0,
        "CreatedAt": 0,
        "CreatedBy": 0,
        "UpdatedAt": 0,
        "UpdatedBy": 0,
    }).All(&result)
    

    The above query will result in documents where the listed fields will not be present, so you don't have to manually remove them using delete().