首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Go MongoDB嵌套查询与$lookup

Go MongoDB嵌套查询与$lookup
EN

Stack Overflow用户
提问于 2022-03-07 21:14:09
回答 2查看 452关注 0票数 1

我有一个非常复杂的查询,我需要为我的项目,似乎找不到它的工作实现。下面的函数可以工作,但是现在我需要添加一个$lookup语句来填充profile对象。如您所见,每个匹配都有一个PartnerApartnerB类型的Partner。每个Partner都有一个LiteOffer女巫有一个配置文件。需要从配置文件集合中添加配置文件,使用PartnerA.IDPartnerB.ID作为查找的localFields。

基本上,问题是:我在函数中接收到一个Partner.ID,它也是profile集合中配置文件的id。然后,我需要从matches集合中筛选出在PartnerA或PartnerB中具有相同Partner.ID的所有Partner.ID(只有一个合作伙伴具有相同的ID,而另一个则有不同的ID)。最后,我必须使用mongo $lookup来使用相应的PartnerA.Offer.Profile和PartnerB.Offer.Profile检索配置文件。

下面是匹配结构(我删除了许多字段,以便更容易阅读):

代码语言:javascript
复制
type Match struct {
    ID        primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
    PartnerA  Partner            `json:"partnerA" bson:"partnerA"`
    PartnerB  Partner            `json:"partnerB" bson:"partnerB"`
    Unlocked  bool               `json:"unlocked" bson:"unlocked"`
    DeletedAt time.Time          `json:"deletedAt,omitempty" bson:"deletedAt,omitempty"`
}

type Partner struct {
    ID               primitive.ObjectID `json:"id,omitempty" bson:"id,omitempty"`
    Offer            LiteOffer          `json:"offer,omitempty" bson:"offer,omitempty"`
    LooksInteresting bool               `json:"looksInteresting" bson:"looksInteresting"`
    Unlocked         bool               `json:"unlocked" bson:"unlocked"`
}

type LiteOffer struct {
    ID           primitive.ObjectID `json:"id,omitempty" bson:"id,omitempty"`
    Tags         []Tag              `json:"tags" bson:"tags,omitempty"`
    Profile      Profile            `json:"profile,omitempty" bson:"profile,omitempty"`
}

type Profile struct {
    ID          primitive.ObjectID `json:"id,omitempty" bson:"id" diff:"-"`
    Name        string             `json:"name,omitempty" bson:"name,omitempty" diff:"-"`
    Surname     string             `json:"surname,omitempty" bson:"surname,omitempty" 
}

这是我的功能:

代码语言:javascript
复制
func getMatchesByProfileId(id primitive.ObjectID) (*[]Match, error) {
    var matches []Match

    filter := bson.M{
        "$or": []bson.M{
            {
                "partnerA.id":               id,
                "partnerA.looksInteresting": false,
            },
            {
                "partnerB.id":               id,
                "partnerB.looksInteresting": false,
            },
        },
        "unlocked":  false,
        "deletedAt": nil,
    }

    ctx, _ := db.GetTimeoutContext()
    result, err := getMatchCollection().Find(ctx, filter)
    if err != nil {
        log.Error("Could not find matches, Error: ", err)
        return nil, err
    }

    for result.Next(ctx) {
        var m Match
        if err = result.Decode(&m); err != nil {
            log.Error("Could not decode offer in getMatchesByProfileId", err)
            return nil, err
        }
        matches = append(matches, m)
    }
    return &matches, nil
}

下面是我使用的一个可以工作的管道,但现在我需要将这两个查询组合成一个:

代码语言:javascript
复制
    pipeline := mongo.Pipeline{
        {{"$match", match}},
        {{"$lookup", bson.M{
            "from":         "profile",
            "localField":   "partnerA.id",
            "foreignField": "_id",
            "as":           "profile",
        }}},
        {{"$unwind", "$profile"}},
    }

我希望这能解释一切。我花了好几个小时才找到解决办法。任何帮助都将不胜感激。

如果你有任何问题,请随便问。

谢谢!

EN

Stack Overflow用户

回答已采纳

发布于 2022-03-14 17:26:42

所以我自己解决了这个问题,下面是函数代码:

代码语言:javascript
复制
func getMatchesByProfileId(id primitive.ObjectID) (*[]Match, error) {
    var matches []Match

    match := bson.D{
        {"unlocked", false},
        {"deletedAt", nil},
        {"$or", []bson.M{
            {
                "partnerA.id":               id,
                "partnerA.looksInteresting": false,
            },
            {
                "partnerB.id":               id,
                "partnerB.looksInteresting": false,
            },
        }},
    }

    pipeline := mongo.Pipeline{
        {{"$match", match}},
        {{"$lookup", bson.M{
            "from":         "profile",
            "localField":   "partnerA.id",
            "foreignField": "_id",
            "as":           "partnerA.offer.profile",
        }}},
        {{"$unwind", "$partnerA.offer.profile"}},

        {{"$lookup", bson.M{
            "from":         "profile",
            "localField":   "partnerB.id",
            "foreignField": "_id",
            "as":           "partnerB.offer.profile",
        }}},
        {{"$unwind", "$partnerB.offer.profile"}},
    }

    ctx, _ := db.GetTimeoutContext()
    cursor, err := getMatchCollection().Aggregate(ctx, pipeline)
    if err != nil {
        log.Error("Could not aggregate matches, Error: ", err)
        return nil, err
    }

    defer cursor.Close(ctx)

    for cursor.Next(ctx) {
        var m Match
        if err = cursor.Decode(&m); err != nil {
            log.Error("Could not decode matches in getMatchesByProfileId error: ", err)
            return nil, err
        }
        matches = append(matches, m)
    }
    return &matches, nil
}
票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71387340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档