我有一个集合,里面有这样的文档
{
"_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加入基于_id和bsk.bskItems.promotionApplied.bskIds以及_id和bsk.bskItems.id的两者,但我不知道如何做到这一点。
发布于 2017-11-20 17:40:56
我不知道你是否解决了你的问题,或者这是否还相关,但我理解了你的问题:
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"
}但我的建议是下次在你的数据库结构中加入一些想法。你有苹果和梨,所以我们必须做一个亚洲梨才能得到这个结果。此外,从聚合级别可以看出,这并不是一项容易的工作。如果将包含字段product的数组与包含字段promotionApplied的数组分开,这会容易得多。
要分解它并一步一步地解释正在发生的事情:
{
$unwind: "$bsk.bskItems"
}通过解开,我们正在展平我们的数组。我们需要它来访问数组中的字段并对其进行操作。有关$unwind的更多信息
{
$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或您想要的任何值)
"bsk": {
"bskItems": {
"promotionApplied": {
"bskIds": { $ifNull: [ "$bsk.bskItems.promotionApplied.bskIds", [0] ] }
}
}
}在这里,我们为字段"$bsk.bskItems.promotionApplied.bskIds"创建一个数组。因为不是所有的文档都有这个字段,所以我们必须添加到所有文档中,否则我们就是在比较橙子和苹果。
"product": { $ifNull: [ "$bsk.bskItems.product.description", "" ] }如前所述,我们必须使我们的文档看起来都一样,所以我们还将$bsk.bskItems.product.description添加到没有此字段的文档中。如果没有字段,我们将其设置为空字符串
现在我们所有的文档都有了相同的结构,我们可以开始实际的排序了。
{
$unwind: "$bsk.bskItems.promotionApplied.bskIds"
}因为我们想要访问$bsk.bskItems.promotionApplied.bskIds中的ids,所以我们还必须展开这个数组。
{
$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" } }在最终的项目中,我们只是根据我们想要的外观来构建最终的文档。
希望你现在明白为什么思考,我们和我们如何保存东西,很重要。
发布于 2016-07-03 06:14:43
使用文档类型数据库-最好存储升级元数据,而不是只存储id。请参阅附件中的示例
"promotionApplied" : [{
bskId : 4,
name : "name",
otherData : "otherData"
}, {
bskId : 5,
name : "name5",
otherData : "otherData5"
}
]https://stackoverflow.com/questions/38139452
复制相似问题