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下所有当前日期在effectiveStartDteffectiveEndDt之间的合同。

    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)
}
回到顶部