首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在单个集合上使用mongodb $lookup

在单个集合上使用mongodb $lookup
EN

Stack Overflow用户
提问于 2016-07-01 15:24:38
回答 2查看 584关注 0票数 1

我有一个集合,里面有这样的文档

代码语言:javascript
运行
复制
{
    "_id" : ObjectId("5773ac6a486f811694711875"),
    "bsk" : {
        "bskItems" : [ 
            {
                "id" : 4,
                "bskItemLineType" : "SaleItem",
                "product" : {
                    "description" : "reblochon"
                }
            }, 
            {
                "id" : 5,
                "bskItemLineType" : "SaleItem",
                "product" : {
                    "description" : "Pinot Noir"
                }
            }, 
            {
                "id" : 13,
                "bskItemLineType" : "PromotionItem",
                "promotionApplied" : {
                    "bskIds" : [ 
                        4, 
                        5
                    ]
                }
            }, 
            {
                "id" : 8,
                "bskItemLineType" : "SaleItem",
                "product" : {
                    "description" : "Food"
                }
            }, 
            {
                "id" : 10,
                "bskItemLineType" : "SubTotalItem"
            }, 
            {
                "id" : 12,
                "bskItemLineType" : "TenderItem"
            }, 
            {
                "id" : 14,
                "bskItemLineType" : "ChangeDue"
            }
        ]
    }
}

我想要一个输出,在那里我可以看到"promotionsApplied“和它们所应用的项的描述。对于上面的文档,"promotionsApplied“是"bsk.BskItems.id”4和5,所以我希望输出是:

代码语言:javascript
运行
复制
{
    "_id": xxxxx,
    "promotionAppliedto : "reblochon"
},
{

    "_id": xxxxx,
    "promotionAppliedto : "Pinot Noir"
}      

查询如下:

代码语言:javascript
运行
复制
 db.getCollection('DSTest').aggregate([
{$project:{"bsk.bskItems.product.description":1,"bsk.bskItems.id":1}},
{$unwind: "$bsk.bskItems"},

    ])

为我获取描述

代码语言:javascript
运行
复制
db.getCollection('DSTest').aggregate([
{$project:{"bsk.bskItems.promotionApplied.bskIds":1}},

{$unwind: "$bsk.bskItems"},
{$unwind:"$bsk.bskItems.promotionApplied.bskIds"},

    ])

给我申请的促销。我希望能够使用$lookup加入基于_idbsk.bskItems.promotionApplied.bskIds以及_idbsk.bskItems.id的两者,但我不知道如何做到这一点。

EN

回答 2

Stack Overflow用户

发布于 2017-11-20 17:40:56

我不知道你是否解决了你的问题,或者这是否还相关,但我理解了你的问题:

代码语言:javascript
运行
复制
db.DSTest.aggregate([
{
  $unwind: "$bsk.bskItems"
},
{
  $project: {
    baItId: { $ifNull: [ "$bsk.bskItems.id", 0 ] },
    "bsk": { 
      "bskItems": {
        "promotionApplied": {
          "bskIds": { $ifNull: [ "$bsk.bskItems.promotionApplied.bskIds", [0] ] }
          }
        }
      },
      "product": { $ifNull: [ "$bsk.bskItems.product.description", "" ] },
    }
},
{
  $unwind: "$bsk.bskItems.promotionApplied.bskIds"
},
{
  $project: {
     baItId: 1,
     proAppliedId: 
     {
       $cond: { if: { $eq: [ "$bsk.bskItems.promotionApplied.bskIds", 0 ] }, then: "$baItId", else: "$bsk.bskItems.promotionApplied.bskIds" }
     }, 
     product: 1
  }
}, 
{
  $group: {
    _id: { proAppliedId: "$proAppliedId", docId: "$_id"},
    product: { $push:  { "p": "$product" } },
    groupCount: { $sum: 1 }
  }
},
{
  $unwind: "$product"
},
{
  $match: {
    "product.p": {$ne: ""}, "groupCount": { $gt: 1}
  }
},
{
  $project: {
    _id: "$_id.docId",
    "promotionAppliedto": "$product.p"
  }
}
])

使用您提供的虚拟文档,这是我得到的结果:

代码语言:javascript
运行
复制
{ 
    "_id" : ObjectId("5773ac6a486f811694711875"), 
    "promotionAppliedto" : "reblochon"
}
{ 
    "_id" : ObjectId("5773ac6a486f811694711875"), 
    "promotionAppliedto" : "Pinot Noir"
}

但我的建议是下次在你的数据库结构中加入一些想法。你有苹果和梨,所以我们必须做一个亚洲梨才能得到这个结果。此外,从聚合级别可以看出,这并不是一项容易的工作。如果将包含字段product的数组与包含字段promotionApplied的数组分开,这会容易得多。

要分解它并一步一步地解释正在发生的事情:

代码语言:javascript
运行
复制
{
  $unwind: "$bsk.bskItems"
}

通过解开,我们正在展平我们的数组。我们需要它来访问数组中的字段并对其进行操作。有关$unwind的更多信息

代码语言:javascript
运行
复制
{
  $project: {
    baItId: { $ifNull: [ "$bsk.bskItems.id", 0 ] },
    "bsk": { 
      "bskItems": {
        "promotionApplied": {
          "bskIds": { $ifNull: [ "$bsk.bskItems.promotionApplied.bskIds", [0] ] }
          }
        }
      },
      "product": { $ifNull: [ "$bsk.bskItems.product.description", "" ] },
    }
}

baItId: { $ifNull: [ "$bsk.bskItems.id", 0 ] }

使用这一行,我们只需确保每个文档都有一个篮子项id。在您的情况下,它们都是这样的,我只是添加了它以确保。如果某些文档没有该字段的值,我们将其设置为0(您可以将其设置为-1或您想要的任何值)

代码语言:javascript
运行
复制
"bsk": { 
  "bskItems": {
    "promotionApplied": {
      "bskIds": { $ifNull: [ "$bsk.bskItems.promotionApplied.bskIds", [0] ] }
      }
    }
  }

在这里,我们为字段"$bsk.bskItems.promotionApplied.bskIds"创建一个数组。因为不是所有的文档都有这个字段,所以我们必须添加到所有文档中,否则我们就是在比较橙子和苹果。

代码语言:javascript
运行
复制
"product": { $ifNull: [ "$bsk.bskItems.product.description", "" ] }

如前所述,我们必须使我们的文档看起来都一样,所以我们还将$bsk.bskItems.product.description添加到没有此字段的文档中。如果没有字段,我们将其设置为空字符串

现在我们所有的文档都有了相同的结构,我们可以开始实际的排序了。

代码语言:javascript
运行
复制
{
  $unwind: "$bsk.bskItems.promotionApplied.bskIds"
}

因为我们想要访问$bsk.bskItems.promotionApplied.bskIds中的ids,所以我们还必须展开这个数组。

代码语言:javascript
运行
复制
{
  $project: {
     baItId: 1,
     proAppliedId: 
     {
       $cond: { if: { $eq: [ "$bsk.bskItems.promotionApplied.bskIds", 0 ] }, then: "$baItId", else: "$bsk.bskItems.promotionApplied.bskIds" }
     }, 
     product: 1
  }
}

baItId: 1product: 1,正在被传递。proAppliedId将包含我们的bsk.bskItems.promotionApplied.bskIds。如果它们是0,则获得与字段$baItId相同的id,否则它们保持其id不变。

代码语言:javascript
运行
复制
{
  $group: {
    _id: { proAppliedId: "$proAppliedId", docId: "$_id"},
    product: { $push:  { "p": "$product" } },
    groupCount: { $sum: 1 }
  }
}

现在,我们终于可以根据在前面的聚合管道中创建的$proAppliedId对文档进行分组。我们还将产品值推入数组中。因此,现在将有包含两个条目的数组。一个是我们查找的值,另一个是空字符串,因为我们在前面的聚合管道"product": { $ifNull: [ "$bsk.bskItems.product.description", "" ] }中这样做了。我们还创建了一个名为groupCount的新字段来计算分组在一起的文档的数量。

代码语言:javascript
运行
复制
{   $project: {
    _id: "$_id.docId",
    "promotionAppliedto": "$product.p"   } }

在最终的项目中,我们只是根据我们想要的外观来构建最终的文档。

希望你现在明白为什么思考,我们和我们如何保存东西,很重要。

票数 1
EN

Stack Overflow用户

发布于 2016-07-03 06:14:43

使用文档类型数据库-最好存储升级元数据,而不是只存储id。请参阅附件中的示例

代码语言:javascript
运行
复制
"promotionApplied" : [{
        bskId : 4,
        name : "name",
        otherData : "otherData"
    }, {
        bskId : 5,
        name : "name5",
        otherData : "otherData5"
    }
]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38139452

复制
相关文章

相似问题

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