我的文件如下:
{
"_id": "1",
"tags": [
{ "code": "01-01", "type": "machine" },
{ "code": "04-06", "type": "gearbox" },
{ "code": "07-01", "type": "machine" }
]
},
{
"_id": "2",
"tags": [
{ "code": "03-04","type": "gearbox" },
{ "code": "01-01", "type": "machine" },
{ "code": "04-11", "type": "machine" }
]
}
我想仅为类型为" machine"的标签获取不同的代码。因此,对于上面的示例,结果应为["01-01", "07-01", "04-11"]
。
我该怎么做?
答案 0 :(得分:1)
使用$unwind
然后$group
并将标记作为键,将在结果集的单独文档中为您提供每个标记:
db.collection_name.aggregate([
{
$unwind: "$tags"
},
{
$match: {
"tags.type": "machine"
}
},
{
$group: {
_id: "$tags.code"
}
},
{
$project:{
_id:false
code: "$_id"
}
}
]);
或者,如果您希望将它们放入单个文档中的数组中,则可以在第二个$push
阶段内使用$group
:
db.collection_name.aggregate([
{
$unwind: "$tags"
},
{
$match: {
"tags.type": "machine"
}
},
{
$group: {
_id: "$tags.code"
}
},
{
$group:{
_id: null,
codes: {$push: "$_id"}
}
}
]);
另一位用户建议包括{ $match: { "tags.type": "machine" } }
的初始阶段。如果您的数据可能包含大量不包含“machine”标记的文档,那么这是一个好主意。这样您就可以消除对这些文档的不必要处理。你的管道看起来像这样:
db.collection_name.aggregate([
{
$match: {
"tags.type": "machine"
}
},
{
$unwind: "$tags"
},
{
$match: {
"tags.type": "machine"
}
},
{
$group: {
_id: "$tags.code"
}
},
{
$group:{
_id: null,
codes: {$push: "$_id"}
}
}
]);
答案 1 :(得分:1)
> db.foo.aggregate( [
... { $unwind : "$tags" },
... { $match : { "tags.type" : "machine" } },
... { $group : { "_id" : "$tags.code" } },
... { $group : { _id : null , "codes" : {$push : "$_id"} }}
... ] )
{ "_id" : null, "codes" : [ "04-11", "07-01", "01-01" ] }
答案 2 :(得分:1)
更好的方法是直接在 tags.type 上分组,并在 tags.code 上使用 addToSet
以下是我们如何在3个聚合阶段实现相同的输出:
db.name.aggregate([
{$unwind:"$tags"},
{$match:{"tags.type":"machine"}},
{$group:{_id:"$tags.type","codes":{$addToSet:"$tags.code"}}}
])
输出:{“_ id”:“机器”,“代码”: [“04-11”,“07-01”,“01-01”] }
另外,如果您希望过滤掉tag.type代码,我们只需要在匹配阶段将“machine”替换为所需的tag.type。