我有一个看起来像这样的数据集:
{
"id": "02741544",
"items": [{
"item": "A"
}]
}, {
"id": "02472691",
"items": [{
"item": "A"
}, {
"item": "B"
}, {
"item": "C"
}]
}, {
"id": "01316523",
"items": [{
"item": "A"
}, {
"item": "B"
}]
}, {
"id": "01316526",
"items": [{
"item": "A"
}, {
"item": "B"
}]
}, {
"id": "01316529",
"items": [{
"item": "A"
}, {
"item": "D"
}]
},
我正在尝试创建一个查询,它会给我一个如下所示的输出:
{
"item": "A",
"ids": [{
"id": "02741544"
}, {
"id": "02472691"
}, {
"id": "01316523"
}, {
"id": "01316526"
}, {
"id": "01316529"
}]
}, {
"item": "B",
"ids": [{
"id": "02472691"
}, {
"id": "01316523"
}, {
"id": "01316526"
}]
}, {
"item": "C",
"ids": [{
"id": "02472691"
}]
}, {
"item": "D",
"ids": [{
"id": "02472691"
}]
},
基本上,我正在尝试从对象中的item数组中获取不同的项,然后为每个obj返回一个id数组,其中包含该项的数组。
答案 0 :(得分:2)
更好地使用aggregation framework运行包含以下管道步骤(按给定顺序)的操作:
$unwind
- 此初始步骤将展平items
数组,即它会为每个数组条目生成每个文档的副本。这对于在管道中进一步处理文档是必要的,因为"非规范化"您可以汇总为组的文档。$group
- 这会按照item
子文档密钥对展平的文档进行分组,并使用 {{3}创建ids
列表} 累加器运算符。 - 更新 -
正如@AminJ在评论中指出的那样,如果items
可能有重复的项目值,并且您不希望结果中出现重复的ID,则可以使用 $push
而不是 $addToSet
以下示例演示了这一点:
db.collection.aggregate([
{ "$unwind": "$items" },
{
"$group": {
"_id": "$items.item",
"ids": {
"$push": { "id": "$id" } /* or use
"$addToSet": { "id": "$id" } if you don't want duplicate ids */
}
}
}
])
示例输出
{
"_id" : "A",
"ids" : [
{ "id" : "02741544" },
{ "id" : "02472691" },
{ "id" : "01316523" },
{ "id" : "01316526" },
{ "id" : "01316529" }
]
}
/* 2 */
{
"_id" : "B",
"ids" : [
{ "id" : "02472691" },
{ "id" : "01316523" },
{ "id" : "01316526" }
]
}
/* 3 */
{
"_id" : "C",
"ids" : [
{ "id" : "02472691" }
]
}
/* 4 */
{
"_id" : "D",
"ids" : [
{ "id" : "01316529" }
]
}
$push
函数的结果是聚合管道操作最后阶段生成的文档的游标。因此,如果您希望结果在数组中,您可以使用光标的 aggregate()
方法,该方法返回包含其中所有文档的数组。
例如:
var pipeline = [
{ "$unwind": "$items" },
{
"$group": {
"_id": "$items.item",
"ids": {
"$push": { "id": "$id" } /* or use
"$addToSet": { "id": "$id" } if you don't want duplicate ids */
}
}
}
],
results = db.collection.aggregate(pipeline).toArray();
printjson(results);
答案 1 :(得分:0)
以下是使用汇总管道的解决方案:
db.col.aggregate([
{
$unwind: "$items"
},
{
$project: {
id: 1,
item: "$items.item"
}
},
{
$group: {
_id: "$item",
ids: {
$push: "$id"
}
}
}
])