我在MongoDB中有一个包含以下模式的文档:
{
"_id" : {
"id" : "ID1",
"type" : "TYPE1"
},
"attrs" : [
{
"name" : "ATTR1",
"value" : "foo"
},
{
"name" : "ATTR2",
"type" : "bar"
},
...
{
"name" : "ATTRn",
"value" : "blabla"
}
]
}
集合中的每个文档都代表一个实体(具有唯一的ID和类型)和一组属性。每个文档可以具有多个属性,甚至属于相同类型(即具有相同_id.type
的两个文档可以具有不同的属性集)。
我想获取与给定类型相关联的属性的名称(实际上,属性集的并集)。我尝试使用以下内容:
db.runCommand({aggregate: "col", pipeline: [ {$group: {_id: "$_id.type", attr: {$addToSet: "$attrs.name"}} }]})
结果是:
{
"result" : [
{
"_id" : "TYPE1",
"attr" : [
[
"ATTR1",
"ATTR2",
"ATTR3"
],
[
"ATTR4",
"ATTR5"
]
]
},
...
],
"ok" : 1
}
问题是$addToSet
在添加数组元素时不会逐个元素地处理。而不是那样,它将整个数组视为单个元素。因此,最后得到的是一个"数组阵列"而我想拥有的是这样的:
{
"result" : [
{
"_id" : "TYPE1",
"attr" : [
"ATTR1",
"ATTR2",
"ATTR3",
"ATTR4",
"ATTR5"
]
},
...
],
"ok" : 1
}
如何重新制作上述查询以获得此结果?
答案 0 :(得分:3)
在分组之前,您需要$unwind
attrs
数组:
db.col.aggregate([
{$unwind: '$attrs'},
{$group: {_id: "$_id.type", attr: {$addToSet: "$attrs.name"}} }
])
输出:
{
"result" : [
{
"_id" : "TYPE1",
"attr" : [
"ATTRn",
"ATTR2",
"ATTR1"
]
}
],
"ok" : 1
}
$unwind
每个文档重复一次,每个attr
元素一次。
答案 1 :(得分:1)
$addToSet
与$each
相结合,可以完美地保存和更新,只要它们不存在 。
{ $addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
参考:https://docs.mongodb.com/manual/reference/operator/update/each/#up._S_each