Golang中如何从子文档获取日期时间字段
Golang中如何从子文档获取日期时间字段 我有一个类似这样的MongoDB文档
文档
{
"_id" : ObjectId("5f73845ffb2a1a44d94d1245"),
"version" : 1.0,
"employerId" : "123456",
"firstName" : "test",
"lastName" : "testname",
"contract" : [
{
"effectiveStartDt" : ISODate("2020-09-06T00:00:00.000Z"),
"effectiveEndDt" : ISODate("2020-09-30T00:00:05.000Z"),
"vendorName" : "Accenture"
},
{
"effectiveStartDt" : ISODate("2020-10-06T00:00:00.000Z"),
"effectiveEndDt" : ISODate("2020-10-31T00:00:00.000Z"),
"vendorName" : "TCS"
}
]
}
我写了一个查询,用于查找某个雇主ID下所有当前日期在effectiveStartDt和effectiveEndDt之间的合同。
err := cursor.Decode(&contract)
return contract
Go结构体定义如下:
type Contract struct {
VendorName string `json:"vendorName" bson:"vendorName"`
EffectiveStartDt *time.Time `json:"effectiveStartDt" bson:"effectiveStartDt"`
EffectiveEndDt *time.Time `json:"effectiveEndDt" bson:"effectiveEndDt"`
}
结果结构体将日期设置为null:
[
{
"vendorName": "TCS",
"effectiveStartDt": null,
"effectiveEndDt": null
}
]
如果您能就此提供帮助,我将不胜感激。
更多关于Golang中如何从子文档获取日期时间字段的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中如何从子文档获取日期时间字段的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题在于你的Go结构体定义与MongoDB文档结构不匹配。MongoDB文档中的contract是一个数组,但你的结构体只定义了单个合同字段。你需要创建一个包含合同数组的父结构体。
以下是正确的结构体定义和查询示例:
type Employee struct {
ID string `bson:"_id"`
EmployerID string `bson:"employerId"`
Contracts []Contract `bson:"contract"`
}
type Contract struct {
VendorName string `bson:"vendorName"`
EffectiveStartDt *time.Time `bson:"effectiveStartDt"`
EffectiveEndDt *time.Time `bson:"effectiveEndDt"`
}
查询当前有效合同的示例代码:
func getCurrentContracts(employerID string) ([]Contract, error) {
collection := client.Database("yourdb").Collection("employees")
now := time.Now()
pipeline := []bson.M{
{
"$match": bson.M{
"employerId": employerID,
},
},
{
"$unwind": "$contract",
},
{
"$match": bson.M{
"contract.effectiveStartDt": bson.M{"$lte": now},
"contract.effectiveEndDt": bson.M{"$gte": now},
},
},
{
"$replaceRoot": bson.M{
"newRoot": "$contract",
},
},
}
cursor, err := collection.Aggregate(context.Background(), pipeline)
if err != nil {
return nil, err
}
defer cursor.Close(context.Background())
var contracts []Contract
if err = cursor.All(context.Background(), &contracts); err != nil {
return nil, err
}
return contracts, nil
}
或者使用Find查询并解码到完整结构体:
func getEmployeeWithContracts(employerID string) (*Employee, error) {
collection := client.Database("yourdb").Collection("employees")
var employee Employee
err := collection.FindOne(context.Background(),
bson.M{"employerId": employerID},
).Decode(&employee)
if err != nil {
return nil, err
}
return &employee, nil
}
获取当前有效合同的过滤函数:
func filterCurrentContracts(contracts []Contract) []Contract {
now := time.Now()
var current []Contract
for _, contract := range contracts {
if contract.EffectiveStartDt != nil &&
contract.EffectiveEndDt != nil &&
contract.EffectiveStartDt.Before(now) &&
contract.EffectiveEndDt.After(now) {
current = append(current, contract)
}
}
return current
}
使用示例:
employee, err := getEmployeeWithContracts("123456")
if err != nil {
log.Fatal(err)
}
currentContracts := filterCurrentContracts(employee.Contracts)
for _, contract := range currentContracts {
fmt.Printf("Vendor: %s, Start: %v, End: %v\n",
contract.VendorName,
contract.EffectiveStartDt,
contract.EffectiveEndDt)
}

