在单个集合上使用mongodb$查找
我收集了这样的文件在单个集合上使用mongodb$查找,mongodb,lookup,Mongodb,Lookup,我收集了这样的文件 { "_id" : ObjectId("5773ac6a486f811694711875"), "bsk" : { "bskItems" : [ { "id" : 4, "bskItemLineType" : "SaleItem", "product" : { "description
{
"_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,因此我希望输出为:
{
"_id": xxxxx,
"promotionAppliedto : "reblochon"
},
{
"_id": xxxxx,
"promotionAppliedto : "Pinot Noir"
}
查询如下:
db.getCollection('DSTest').aggregate([
{$project:{"bsk.bskItems.product.description":1,"bsk.bskItems.id":1}},
{$unwind: "$bsk.bskItems"},
])
给我描述一下
db.getCollection('DSTest').aggregate([
{$project:{"bsk.bskItems.promotionApplied.bskIds":1}},
{$unwind: "$bsk.bskItems"},
{$unwind:"$bsk.bskItems.promotionApplied.bskIds"},
])
让我申请晋升。我希望能够使用
$lookup
基于\u id
和bsk.bskItems.promotionapplicated.bskIds
和\u id
和bsk.bskItems.id
加入这两个,但我不知道如何加入。使用文档类型数据库-最好存储促销metadtaa,而不是只存储id。
请参阅附件中的示例
"promotionApplied" : [{
bskId : 4,
name : "name",
otherData : "otherData"
}, {
bskId : 5,
name : "name5",
otherData : "otherData5"
}
]
我不知道你是否解决了你的问题,或者这是否与问题有关,但我发现了你的问题:
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"
}
}
])
对于您提供的虚拟文档,这是我得到的结果:
{
"_id" : ObjectId("5773ac6a486f811694711875"),
"promotionAppliedto" : "reblochon"
}
{
"_id" : ObjectId("5773ac6a486f811694711875"),
"promotionAppliedto" : "Pinot Noir"
}
但我的建议是下次在数据库结构中考虑一下。你有苹果和梨,所以我们必须做一个亚洲梨才能得到这个结果。从聚合级别上看,这也不是一件容易的工作。如果您将包含产品
字段的数组与包含促销应用
字段的数组分开,那么这可能会容易得多
要将其分解并逐步解释发生的情况:
{
$unwind: "$bsk.bskItems"
}
通过展开,我们将阵列展平。为了访问数组中的字段并对其执行操作,我们需要使用它。更多关于
在这一行中,我们只是确保每个文档都有一个篮子项目id。在您的情况下,他们都有,我只是添加了它来确保。如果某个文档没有该字段的值,我们将其设置为0(您可以将其设置为-1或任何您想要的值)
这里我们正在为字段“$bsk.bskItems.promotionapplicated.bskIds”
创建一个数组。由于并非所有文档都有此字段,我们必须将其全部添加到文档中,否则我们将比较橙子和苹果
"product": { $ifNull: [ "$bsk.bskItems.product.description", "" ] }
如前所述,我们必须使我们的文档看起来都一样,因此我们还将$bsk.bskItems.product.description
添加到没有此字段的文档中。对于没有字段的用户,我们将其设置为空字符串
现在,我们所有的文档都具有相同的结构,我们可以从实际的排序开始
{
$unwind: "$bsk.bskItems.promotionApplied.bskIds"
}
因为我们想访问$bsk.bskItems.promotionApplied.bskIds
中的ID,所以我们还必须解开这个数组
{
$project: {
baItId: 1,
proAppliedId:
{
$cond: { if: { $eq: [ "$bsk.bskItems.promotionApplied.bskIds", 0 ] }, then: "$baItId", else: "$bsk.bskItems.promotionApplied.bskIds" }
},
product: 1
}
}
baItId:1
和product:1
正在被传递。proAppliedId
将包含我们的bsk.bskItems.promotionApplied.bskIds
。如果它们为0,则它们将获得与字段$baItId
相同的id,否则它们将保留其id
{
$group: {
_id: { proAppliedId: "$proAppliedId", docId: "$_id"},
product: { $push: { "p": "$product" } },
groupCount: { $sum: 1 }
}
}
现在,我们终于可以通过在前面的聚合管道中创建的$proAppliedId
对文档进行分组。
我们还将产品值推送到一个数组中。因此,现在将有包含两个条目的数组。
一个是我们要查找的值,另一个是空字符串,因为我们在以前的聚合管道“product”:{$ifNull:[“$bsk.bskItems.product.description”,“]}
我们还创建了一个名为groupCount
的新字段来统计分组在一起的文档
{ $project: {
_id: "$_id.docId",
"promotionAppliedto": "$product.p" } }
在最终项目中,我们只是按照我们希望的样子构建最终文档
希望您现在理解思考的原因,以及我们如何保存东西,这很重要。我建议您调整文档结构,而不是尝试自我引用。MongoDB不是一个传统的数据库。你可能是对的,只是觉得复制描述是不对的,但我看不到其他方法。
{
$group: {
_id: { proAppliedId: "$proAppliedId", docId: "$_id"},
product: { $push: { "p": "$product" } },
groupCount: { $sum: 1 }
}
}
{ $project: {
_id: "$_id.docId",
"promotionAppliedto": "$product.p" } }