我有客户与API交互的日志文件。我想解析这些日志并将结果提供到结构图中,以便我可以将数据组织成有用的信息。例如,我想回复以下问题:“向我显示每个用户每天的请求总数”。
我已经创建了一个看似合适的结构来保存数据。但是,当我尝试运行程序时,我收到错误:invalid operation: dates[fields[1]] (type *Dates does not support indexing) [process exited with non-zero status]
。
http://play.golang.org/p/8u3jX26ktt
package main
import (
"fmt"
"strings"
)
type Stats struct {
totalNumberOfRequests int
}
type Customer struct {
listOfCustomers map[string]Stats // map[customerid]Stats
}
type Dates struct {
listOfDates map[string]Customer // map[date]Customer
}
var requestLog = []string{
"2011-10-05, 1234, apiquery",
"2011-10-06, 1234, apiquery",
"2011-10-06, 5678, apiquery",
"2011-10-09, 1234, apiquery",
"2011-10-12, 1234, apiquery",
"2011-10-13, 1234, apiquery",
}
func main() {
dates := new(Dates)
for _, entry := range requestLog {
fmt.Println("entry:", entry)
fields := strings.Split(entry, "'")
dates.listOfDates[fields[0]].listOfCustomers[fields[1]].totalNumberOfRequests++
}
}
是否有更好的结构使用?或者有没有办法让这个结构适合这个特定目的?
答案 0 :(得分:1)
如果我理解您对输出的期望,这是一个解决方案。但是我不喜欢“客户是带有id和Stat的地图..我认为它应该是一个带有两个字段(cid string
和stat Stats
)的更简单的结构。此外,日期结构不允许对于同一天的多个客户,我已将其更改为将单个日期映射到用户列表。
我还添加了更多“测试场景”,以涵盖客户在同一天多次访问资源的情况。
您似乎没有使用“apiquery”您的示例,因此下面的代码与它不匹配。
关于结构中指针的更改 - 请参阅this issue(如您问题的评论中所述)
package main
import (
"fmt"
"strings"
)
type Stats struct {
totalNumberOfRequests int
}
type Customer struct {
customerWithStat map[string]*Stats // a customer with it's corresponding stats
}
type Dates struct {
listOfDates map[string][]*Customer // map[date]list of customers (for each date)
}
var requestLog = []string{
"2011-10-05, 1234, apiquery",
"2011-10-06, 5678, apiquery",
"2011-10-06, 1234, apiquery",
"2011-10-06, 1234, apiquery",
"2011-10-06, 5678, apiquery",
"2011-10-06, 1234, apiquery",
"2011-10-09, 1234, apiquery",
"2011-10-12, 1234, apiquery",
"2011-10-13, 1234, apiquery",
"2011-10-13, 1234, apiquery",
"2011-10-06, 1234, apiquery",
}
func main() {
listOfDates := make(map[string][]*Customer)
dates := Dates{listOfDates}
for _, entry := range requestLog {
fields := strings.Split(entry, ",")
curDateStr := strings.TrimSpace(fields[0])
curCustIdStr := strings.TrimSpace(fields[1])
if customersAtDate, dateExists := dates.listOfDates[curDateStr]; dateExists {
// Date already exist
for _, curCustomer := range customersAtDate {
if curStat, customerExists := curCustomer.customerWithStat[curCustIdStr]; customerExists {
// The user has already accessed this resource - just increment
curStat.totalNumberOfRequests++
} else {
// New user - set access to 1
curCustomer.customerWithStat[curCustIdStr] = &Stats{1}
}
}
} else {
// New Date
// Init the Statistic for the new customer
newCustomerData := make(map[string]*Stats)
newCustomerData[curCustIdStr] = &Stats{1}
// Create the customer itself
newCustomer := &Customer{newCustomerData}
// add to the current day list
dates.listOfDates[curDateStr] = append(dates.listOfDates[curDateStr], newCustomer)
}
}
// Print result
for date, customers := range dates.listOfDates {
fmt.Println("Date: ", date)
for _, customer := range customers {
for cid, stat := range customer.customerWithStat {
fmt.Println(" Customer: ", cid)
fmt.Println(" # Requests: ", *stat)
}
}
}
}
这将输出:
Date: 2011-10-05
Customer: 1234
# Requests: {1}
Date: 2011-10-06
Customer: 5678
# Requests: {2}
Customer: 1234
# Requests: {4}
Date: 2011-10-09
Customer: 1234
# Requests: {1}
Date: 2011-10-12
Customer: 1234
# Requests: {1}
Date: 2011-10-13
Customer: 1234
# Requests: {2}