Получение ошибки при удалении значения ключа из массива объектов - PullRequest
0 голосов
/ 09 апреля 2020

Я получаю следующую ошибку при удалении из ключа из массива JSON объектов, используя Go. Ошибка:

    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 {}

Я объясняю свой код ниже.

    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
        }
    }

Здесь я выбираю некоторые записи из MongoDB и удаляю некоторые значения ключа из каждой записи, но когда я запускаю сервер Я получаю эти ошибки. Как я начинающий Go. Кто-нибудь может мне помочь исправить эти ошибки?

Ответы [ 2 ]

3 голосов
/ 09 апреля 2020

Сообщение об ошибке говорит само за себя: первый аргумент для встроенного delete() должен быть значением типа карты stati c.

Ваша переменная result имеет введите []interface{}, поэтому его индексирование, например result[i], приведет к значению типа interface{}.

Если он содержит карту, вы можете использовать утверждение типа для получения карты ценность от этого. Поскольку вы используете драйвер mgo, он имеет тип bson.M (то есть map[string]interface{}), поэтому вы можете сделать это следующим образом:

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

Но это было бы лучше, если бы вы сначала объявили result срезом карт:

var result []bson.M

Так что тогда утверждение типа не понадобится, и следующий код будет действительным:

delete(result[i], "_id")

Также обратите внимание, что если вы хотите удалить эти свойства из результатов, было бы лучше, если бы вы сказали MongoDB, что вам не нужны эти поля, и поэтому сервер даже не отправит их (сохраняя трафик сети). c) и тогда вам не придется их удалять (экономя время и память).

Используйте проекцию, чтобы сказать, что вам не нужны эти поля. В mgo вы можете установить проекцию, используя метод Query.Select().

Например:

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

Приведенный выше запрос приведет к документам, в которых перечислены поля не будут присутствовать, поэтому вам не нужно удалять их вручную, используя delete().

0 голосов
/ 09 апреля 2020

Вы пытаетесь удалить ключ из переменной типа interface{}. @icza дает хорошее решение.

Вы можете использовать .Select(), чтобы выбрать, какие поля должны быть получены для результатов. Тогда вам не нужно удалять эти поля из каждого объекта.

Например, следующий запрос будет только извлекать поле имени и возраста:

err := db.C(ORDERCOLLECTION).Find(nil).Select(bson.M{"name": 1, "age": 1}).All(&result)
...