Golang中MongoDB数据解析问题求助

Golang中MongoDB数据解析问题求助 大家好,

我正在处理从MongoDB收集数据并解析它以进行后续处理的工作。在处理原始结构和接口时遇到了问题。我有一个递归函数用于遍历结构,但它无法正确处理数据库查询的结果。有人能帮忙看看吗?

func parseMap(fullPath string, mykey string, data map[string]map[string]string,aMap map[string]interface{}) map[string]map[string]string {

for key, val := range aMap {
	
	switch concreteVal := val.(type) {
	case map[string]interface{}:
		if DEBUG {
			fmt.Println(key)
		}
		if (len(fullPath) < 1) {
			fullPath = key
		} else {
			fullPath = fullPath+"->"+key
		}
		parseMap(fullPath, mykey, data, val.(map[string]interface{}))
	case []interface{}:
		if DEBUG {
			fmt.Println(key)
		}
		
		subkey := key
		
		if (len(fullPath) < 1) {
			fullPath = key
		} else {
			fullPath = fullPath+"->"+key
		}
		parseArray(fullPath,mykey, data, subkey, val.([]interface{}))
	case bool:
		if DEBUG {
			fmt.Println("bool ",key, ":", concreteVal)
		}
		tempKey := fullPath+"->"+key
		data[mykey][tempKey] = strconv.FormatBool(concreteVal)
	case float64:
		if DEBUG {
			fmt.Println("float ",key, ":", concreteVal)
		}
		tempKey := fullPath+"->"+key
		data[mykey][tempKey] = strconv.FormatFloat(concreteVal, 'f', -1, 64)
	default:
		if DEBUG {
				fmt.Println(key, ":", concreteVal)
		}
		tempKey := fullPath+"->"+key
		if ((concreteVal == nil) || (concreteVal.(string) == "")) {
			data[mykey][tempKey] = "NA"
		} else {
			data[mykey][tempKey] = concreteVal.(string)	
		}
	}
}
return data

}
func parseArray(fullPath string,mykey string, data map[string]map[string]string, subkey string,anArray []interface{}) {
for i, val := range anArray {

	if DEBUG {
		fmt.Println("Index", i, ":", val)
	}
	
	switch concreteVal := val.(type) {
	
	case map[string]interface{}:
		if DEBUG {
			fmt.Println("Index:", i)
		}

		
		parseMap(fullPath,mykey,data, val.(map[string]interface{}))
	case []interface{}:
		if DEBUG {
			fmt.Println("Index:", i)
		}
		fullPath = fullPath+"->"+strconv.Itoa(i)
		parseArray(fullPath,mykey,data, subkey, val.([]interface{}))
	default:
		
		data[mykey][fullPath+strconv.Itoa(i)] = concreteVal.(string)

	}
}

}
func getMongoDbData() map[string]map[string]string {

    baseUrl = "<mystring>"
    mongoDb = "ansible_db"

    uri := baseUrl+mongoDb

    ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
    defer cancel()

    //fmt.Printf("uri = '%s'\n",uri)

    client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
    if err != nil {
            panic(err)
    }

    defer func() {
            if err = client.Disconnect(ctx); err != nil {
                    panic(err)
            }
    }()

    myMongoDb := client.Database(mongoDb)
    myCollection := myMongoDb.Collection("cache")

    cursor,err := myCollection.Find(ctx, bson.M{})
    if err != nil {
            log.Fatal(err)
    }

    var data = map[string]map[string]string{}

    defer cursor.Close(ctx)
    for cursor.Next(ctx) {
            var episode bson.M

            if err = cursor.Decode(&episode); err != nil {
                    log.Fatal(err)
            }
            fmt.Println(episode["_id"])
            //fmt.Println(episode)


            data[episode["_id"].(string)] = make(map[string]string)

            data = parseMap("",episode["_id"].(string),data, map[string]interface{}(episode))
    }
    return data

}

查询数据和错误信息:

ansible_facts_hoyt01.mydoman.com
map[_id:ansible_facts_hoyt01.mydoman.com data:map[_ansible_facts_gathered:true ansible_architecture:64-bit ansible_bios_date:12/12/2018 ansible_bios_version:6.00 ansible_date_time:map[date:2020-07-14 day:14 epoch:1594731194.71786 hour:12 iso8601:2020-07-14T12:53:14Z iso8601_basic:20200714T125314713856 iso8601_basic_short:20200714T125314 iso8601_micro:2020-07-14T12:53:14.713856Z minute:53 month:07 second:14 time:12:53:14 tz:UTC tz_offset:+00:00 weekday:Tuesday weekday_number:2 weeknumber:28 year:2020] ansible_distribution:Microsoft Windows Server 2016 Standard ansible_distribution_major_version:10 ansible_distribution_version:10.0.14393.0 ansible_domain:mydoman.com ansible_env:map[ALLUSERSPROFILE:C:\ProgramData APPDATA:C:\Users\ansible\AppData\Roaming COMPUTERNAME:hoyt01 CP_DELIM:; ComSpec:C:\Windows\system32\cmd.exe CommonProgramFiles:C:\Program Files\Common Files CommonProgramFiles(x86):C:\Program Files (x86)\Common Files CommonProgramW6432:C:\Program Files\Common Files HOMEDRIVE:C: HOMEPATH:\Windows JAVA_HOME:C:\PROGRA~1\Java\JDK18~1.0_2 KR_DATA_DIR:C:\PROGRA~3\Nuance\Krypton KR_HOME:C:\PROGRA~1\Nuance\Krypton LOCALAPPDATA:C:\Users\ansible\AppData\Local MEE_HOME:C:\PROGRA~1\Nuance\MEANIN~1 NAA_HOME:C:\PROGRA~1\Nuance\AUTOMA~1 NLE_HOME:C:\PROGRA~1\Nuance\NATURA~1 NLPS_HOME:C:\PROGRA~1\Nuance\nlps NRM_DATA_DIR:C:\ProgramData\Nuance\nrm NRM_HOME:C:\PROGRA~1\Nuance\nrm NSSSVRSDK:C:\Program Files (x86)\Nuance\Speech Server\Server NUANCE:C:\PROGRA~2\COMMON~1\Nuance\Common NUANCE_DATA_DIR:C:\ProgramData\Nuance\Enterprise NUANCE_LICMGR:C:\Program Files\Nuance\license_manager NUANCE_OAM64:C:/PROGRA~1/COMMON~1/Nuance/Common/amd64/bin NUANCE_VERSION:C:\PROGRA~2\COMMON~1\Nuance\Common NUANCE_VERSION_CFG:C:\PROGRA~2\COMMON~1\Nuance\Common\config NUMBER_OF_PROCESSORS:6 OS:Windows_NT PATHEXT:.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL PROCESSOR_ARCHITECTURE:AMD64 PROCESSOR_IDENTIFIER:Intel64 Family 6 Model 85 Stepping 4, GenuineIntel PROCESSOR_LEVEL:6 PROCESSOR_REVISION:5504 PSExecutionPolicyPreference:Bypass PSModulePath:C:\Users\ansible\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules PUBLIC:C:\Users\Public Path:C:\Program Files\Nuance\Text Processing Engine\lib;C:\Program Files\Nuance\Krypton\bin;C:\Program Files\Nuance\Krypton\lib;C:\Program Files (x86)\Nuance\Speech Server\Server\bin;C:\Program Files\Nuance\Recognizer\Recognizer Service\amd64\bin;C:\Program Files\Common Files\Nuance\Common\amd64\bin;C:\Program Files\Nuance\Recognizer\x86\bin;C:\Program Files\Nuance\Recognizer\amd64\bin;C:\PROGRA~2\COMMON~1\Nuance\Common\x86\bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\Nuance\Vocalizer for Enterprise\NVS Service\amd64\bin;C:\Program Files\Nuance\Vocalizer for Enterprise\common\speech\components;C:\Program Files\Nuance\Natural Language Engine\native;C:\Users\ansible\AppData\Local\Microsoft\WindowsApps ProgramData:C:\ProgramData ProgramFiles:C:\Program Files ProgramFiles(x86):C:\Program Files (x86) ProgramW6432:C:\Program Files SNMPCONFPATH:C:\Program Files (x86)\Common Files\Nuance\Common\config SWICOMMONSDK:C:\Program Files\Nuance\Recognizer SWISRSDK:C:\Program Files\Nuance\Recognizer SystemDrive:C: SystemRoot:C:\Windows TEMP:C:\Users\ansible\AppData\Local\Temp TEXTPROC_HOME:C:\PROGRA~1\Nuance\TEXTPR~1 TMP:C:\Users\ansible\AppData\Local\Temp USERDNSDOMAIN:mydoman.COM USERDOMAIN:mydomain USERNAME:ansible USERPROFILE:C:\Users\ansible VOCALIZER_SDK:C:\Program Files\Nuance\Vocalizer for Enterprise VOCALIZER_VOICE_PATH:C:\Program Files (x86)\Nuance\Vocalizer for Enterprise windir:C:\Windows] ansible_fqdn:hoyt01.mydoman.com ansible_hostname:hoyt01 ansible_interfaces:[map[connection_name:Ethernet0 default_gateway:10.10.155.1 dns_domain: interface_index:11 interface_name:vmxnet3 Ethernet Adapter macaddress:00:50:56:B7:AB:8E]] ansible_ip_addresses:[10.10.155.31] ansible_kernel:10.0.14393.0 ansible_lastboot:2020-06-29 21:27:07Z ansible_machine_id:S-1-5-21-3526958220-83193300-899069053 ansible_memtotal_mb:12288 ansible_netbios_name:hoyt01 ansible_nodename:hoyt01.mydoman.com ansible_os_family:Windows ansible_os_name:Microsoft Windows Server 2016 Standard ansible_os_product_type:server ansible_owner_contact: ansible_owner_name:Windows User ansible_powershell_version:5 ansible_processor:[GenuineIntel Intel® Xeon® Gold 6148 CPU @ 2.40GHz GenuineIntel Intel® Xeon® Gold 6148 CPU @ 2.40GHz GenuineIntel Intel® Xeon® Gold 6148 CPU @ 2.40GHz GenuineIntel Intel® Xeon® Gold 6148 CPU @ 2.40GHz GenuineIntel Intel® Xeon® Gold 6148 CPU @ 2.40GHz GenuineIntel Intel® Xeon® Gold 6148 CPU @ 2.40GHz] ansible_processor_cores:1 ansible_processor_count:6 ansible_processor_threads_per_core:1 ansible_processor_vcpus:6 ansible_product_name:VMware Virtual Platform ansible_product_serial:VMware-42 37 10 fc 7a e6 9f 3e-eb 3b 03 aa b0 f9 f6 41 ansible_reboot_pending: ansible_swaptotal_mb:0 ansible_system:Win32NT ansible_system_description: ansible_system_vendor:VMware, Inc. ansible_uptime_seconds:1265175 ansible_user_dir:C:\Users\ansible ansible_user_gecos: ansible_user_id:ansible ansible_user_sid:S-1-5-21-445662847-3382226374-866147045-1250 ansible_virtualization_role:guest ansible_virtualization_type:VMware ansible_win_rm_certificate_expires:2021-08-26 12:00:00 ansible_windows_domain:mydoman.com ansible_windows_domain_member:true ansible_windows_domain_role:Member server gather_subset:[all] installed_programs_windows:[  ComputerName   : hoyt01 ProgramName    : Notepad++ (64-bit x64) RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Notepad++ DisplayVersion : 7.8.1 VersionMajor   : 7 installdate    :  LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Nuance Product Documentation 11.0.5 RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{04B12C15-557E-4685-B06                  F-59D4694E4C26} DisplayVersion : 11.0.5 VersionMajor   : 11 installdate    : 20200629 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Microsoft Visual C++ 2010  x64 Redistributable - 10.0.40219 RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{1D8E6291-B0D5-35EC-844                  1-6616F567A0F7} DisplayVersion : 10.0.40219 VersionMajor   : 10 installdate    : 20200624 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Nuance Vocalizer for Enterprise 7.4 x86_64 RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{23C30F64-7D16-4299-A5E                  C-59A7B44081CD} DisplayVersion : 7.4.4 VersionMajor   : 7 installdate    : 20200629 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : VMware Tools RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{25932044-BBC8-444F-ACF                  4-7E508054FA12} DisplayVersion : 11.0.5.15389592 VersionMajor   : 11 installdate    : 20200623 LastAccessTime : 6/23/2020 7:02:54 PM  ComputerName   : hoyt01 ProgramName    : Java 8 Update 251 (64-bit) RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{26A24AE4-039D-4CA4-87B                  4-2F64180251F0} DisplayVersion : 8.0.2510.8 VersionMajor   : 8 installdate    : 20200629 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Nuance Natural Language Processing Service 1.3.0 RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{3EFDAB11-3EC6-4540-963                  6-6FAD734F99B4} DisplayVersion : 1.3.0 VersionMajor   : 1 installdate    : 20200629 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Microsoft Visual C++ 2019 X64 Additional Runtime - 14.20.27508 RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{4931385B-094D-4DC5-BD6                  A-5188FE9C51DF} DisplayVersion : 14.20.27508 VersionMajor   : 14 installdate    : 20200623 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Nuance License Manager 11.16.5 x86_64 RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{59C49297-BC31-4710-B4E                  E-E50D1F9A9863} DisplayVersion : 11.16.5 VersionMajor   : 11 installdate    : 20200629 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Java SE Development Kit 8 Update 251 (64-bit) RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{64A3A4F4-B792-11D6-A78                  A-00B0D0180251} DisplayVersion : 8.0.2510.8 VersionMajor   : 8 installdate    : 20200629 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Nuance Text Processing Engine 4.0.2 RegPath        : HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall{68262681-0683-687E-000                  0-4D0D2D682623} DisplayVersion : 4.0.2 VersionMajor   : 4 installdate    : 20200629 LastAccessTime :   ComputerName   : hoyt01 ProgramName    : Nuance Krypton 4.1.0

更多关于Golang中MongoDB数据解析问题求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中MongoDB数据解析问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的代码在处理MongoDB的BSON数据时存在类型断言问题。主要问题在于default分支中对concreteVal的类型断言不准确,当遇到非字符串类型时会panic。以下是修复后的版本:

func parseMap(fullPath string, mykey string, data map[string]map[string]string, aMap map[string]interface{}) map[string]map[string]string {
    for key, val := range aMap {
        switch concreteVal := val.(type) {
        case map[string]interface{}:
            if DEBUG {
                fmt.Println(key)
            }
            newPath := fullPath
            if len(newPath) < 1 {
                newPath = key
            } else {
                newPath = newPath + "->" + key
            }
            parseMap(newPath, mykey, data, concreteVal)
        case []interface{}:
            if DEBUG {
                fmt.Println(key)
            }
            newPath := fullPath
            if len(newPath) < 1 {
                newPath = key
            } else {
                newPath = newPath + "->" + key
            }
            parseArray(newPath, mykey, data, key, concreteVal)
        case bool:
            if DEBUG {
                fmt.Println("bool ", key, ":", concreteVal)
            }
            tempKey := fullPath + "->" + key
            if data[mykey] == nil {
                data[mykey] = make(map[string]string)
            }
            data[mykey][tempKey] = strconv.FormatBool(concreteVal)
        case float64:
            if DEBUG {
                fmt.Println("float ", key, ":", concreteVal)
            }
            tempKey := fullPath + "->" + key
            if data[mykey] == nil {
                data[mykey] = make(map[string]string)
            }
            data[mykey][tempKey] = strconv.FormatFloat(concreteVal, 'f', -1, 64)
        case string:
            if DEBUG {
                fmt.Println("string ", key, ":", concreteVal)
            }
            tempKey := fullPath + "->" + key
            if data[mykey] == nil {
                data[mykey] = make(map[string]string)
            }
            if concreteVal == "" {
                data[mykey][tempKey] = "NA"
            } else {
                data[mykey][tempKey] = concreteVal
            }
        case nil:
            if DEBUG {
                fmt.Println("nil ", key)
            }
            tempKey := fullPath + "->" + key
            if data[mykey] == nil {
                data[mykey] = make(map[string]string)
            }
            data[mykey][tempKey] = "NA"
        default:
            if DEBUG {
                fmt.Println("other type ", key, ":", concreteVal)
            }
            tempKey := fullPath + "->" + key
            if data[mykey] == nil {
                data[mykey] = make(map[string]string)
            }
            data[mykey][tempKey] = fmt.Sprintf("%v", concreteVal)
        }
    }
    return data
}
func parseArray(fullPath string, mykey string, data map[string]map[string]string, subkey string, anArray []interface{}) {
    for i, val := range anArray {
        if DEBUG {
            fmt.Println("Index", i, ":", val)
        }

        switch concreteVal := val.(type) {
        case map[string]interface{}:
            if DEBUG {
                fmt.Println("Index:", i)
            }
            parseMap(fullPath, mykey, data, concreteVal)
        case []interface{}:
            if DEBUG {
                fmt.Println("Index:", i)
            }
            newPath := fullPath + "->" + strconv.Itoa(i)
            parseArray(newPath, mykey, data, subkey, concreteVal)
        default:
            if data[mykey] == nil {
                data[mykey] = make(map[string]string)
            }
            data[mykey][fullPath+"->"+strconv.Itoa(i)] = fmt.Sprintf("%v", concreteVal)
        }
    }
}
func getMongoDbData() map[string]map[string]string {
    baseUrl = "<mystring>"
    mongoDb = "ansible_db"
    uri := baseUrl + mongoDb

    ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
    defer cancel()

    client, err := mongo.Connect(ctx, options.Client().ApplyURI(uri))
    if err != nil {
        panic(err)
    }

    defer func() {
        if err = client.Disconnect(ctx); err != nil {
            panic(err)
        }
    }()

    myMongoDb := client.Database(mongoDb)
    myCollection := myMongoDb.Collection("cache")

    cursor, err := myCollection.Find(ctx, bson.M{})
    if err != nil {
        log.Fatal(err)
    }

    var data = make(map[string]map[string]string)

    defer cursor.Close(ctx)
    for cursor.Next(ctx) {
        var episode bson.M
        if err = cursor.Decode(&episode); err != nil {
            log.Fatal(err)
        }
        
        id, ok := episode["_id"].(string)
        if !ok {
            continue
        }
        
        fmt.Println(id)
        data[id] = make(map[string]string)
        data = parseMap("", id, data, map[string]interface{}(episode))
    }
    
    if err := cursor.Err(); err != nil {
        log.Fatal(err)
    }
    
    return data
}

主要修复点:

  1. parseMap函数中为stringnil类型添加了单独的处理分支
  2. 使用fmt.Sprintf("%v", concreteVal)处理未知类型,避免类型断言panic
  3. 在设置值前检查data[mykey]是否已初始化
  4. 使用concreteVal变量而不是重新进行类型断言
  5. 修复了路径构建的逻辑,避免递归调用时路径累积错误
回到顶部