【问题标题】:Getting error while deleting the key value from array of objects从对象数组中删除键值时出错
【发布时间】:2020-04-09 18:45:38
【问题描述】:

使用 Go 从 JSON 对象数组中删除键时出现以下错误。 错误:

    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 的初学者。谁能帮我解决这些错误?

【问题讨论】:

    标签: mongodb dictionary go bson mgo


    【解决方案1】:

    错误信息说明了一切:内置 delete() 的第一个参数必须是静态类型映射的值。

    您的result 变量的类型为[]interface{},因此像result[i] 一样对其进行索引将产生interface{} 类型的值。

    如果它持有地图,您可以使用type assertion 从中获取地图值。由于您使用mgo 驱动程序,它的类型为bson.M(即map[string]interface{}),因此您可以这样做:

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

    但如果您首先声明 result 为地图切片会更好:

    var result []bson.M
    

    那么就不需要类型断言了,下面就是有效的代码:

    delete(result[i], "_id")
    

    另外请注意,如果您想从结果中删除这些属性,最好告诉 MongoDB 您不需要这些字段,这样服务器甚至不会发送这些(节省网络流量)然后您不必移除它们(节省时间和内存)。

    使用投影来告诉您不需要这些字段。在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() 手动删除它们。

    【讨论】:

    • 是的,我像 delete(result[i].(bson.M), "_id") 一样使用过并且错误消失了。
    • @user_agent 而是将result 声明为[]bson.M,因此您不必使用类型断言。
    • 除了 for 循环之外,还有其他方法可以从每个文档记录中删除相同的键,因为循环需要太多时间。
    • @user_agent 是的,使用投影告诉服务器您不需要这些字段,因此您根本不必删除它们。请参阅编辑后的答案如何做到这一点。
    【解决方案2】:

    您正试图从interface{} 类型的变量中删除键。 @icza 给出了一个很好的解决方案。

    您可以使用.Select() 选择应为结果检索哪些字段。 那么您不需要从每个对象中删除这些字段。

    例如,以下查询将只检索姓名和年龄字段:

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

    【讨论】:

      猜你喜欢
      • 2020-01-20
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 2022-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多