2014-06-23 51 views
1

我正在寻找一种方法来计算文档存在的标签数量。聚合标签正则表达式

数据看起来像以下:

[ 
    { 
     "_id": ObjectId("...."), 
     "tags": ["active-adult", "active-tradeout"] 
    }, 
    { 
     "_id": ObjectId("...."), 
     "tags": ["active-child", "active-tradeout", "active-junk-tag"] 
    }, 
    { 
     "_id": ObjectId("...."), 
     "tags": ["inactive-adult"] 
    } 
] 

这是我想聚合的结果是这样的:

[ 
    { 
     "_id": "active", 
     "total": 2, 
     "subtags": { 
      "adult": 1, 
      "child": 1, 
      "tradeout": 2, 
      "junk-tag": 1 
     } 
    }, 
    { 
     "_id": "inactive", 
     "total": 1, 
     "subtags": { 
      "adult": 1 
     } 
    } 
] 

我知道我可以指望的标签,但我正在寻找正则表达式

db.User.aggregate([ 
    {$unwind: "$tags"}, 
    {$group: {_id: "$tags", total: {$sum: 1}}} 
]) 
+0

我不会使用正则表达式嵌入结构,如stylsheets或xml文件。改为使用算法,或者至少一个可以在更多步骤中以文本形式运行的GREP程序 –

+0

是的,我是这么做的,但是好奇的是,是否有通过聚合框架来实现这一点的方法。 –

回答

1

您可以使用$substr$cond运算符进行小字符串处理,以获得所需的结果(不需要正则表达式)。这将需要MongoDB的2.6+:

db.User.aggregate([ 
    { $unwind : "$tags"}, 
    { $project : { 
     tagType : { 
      $cond : { 
       if : { $eq : [ { $substr : [ "$tags", 0, 6] }, "active" ]}, 
       then: "active", 
       else: "inactive"} 
      }, 
     tag: { 
      $cond : { 
       if : { $eq : [ { $substr : [ "$tags", 0, 6] }, "active" ]}, 
       then: { $substr : ["$tags", 7, -1]}, 
       else: { $substr : ["$tags", 9, -1]}} 
      } 
    }}, 
    { $group : { _id : {tagType : "$tagType", tag: "$tag"} , 
       total: { $sum: 1}}}, 
    { $group : { _id : "$_id.tagType", 
       subtags: { $push : {tag : "$_id.tag", total: "$total"}}, 
       total: { $sum : "$total"}}} 
]); 

此查询的结果将是这样的:

{ 
    "_id" : "inactive", 
    "subtags" : [ 
     { 
      "tag" : "adult", 
      "total" : 1 
     } 
    ], 
    "total" : 1 
} 
{ 
    "_id" : "active", 
    "subtags" : [ 
     { 
      "tag" : "junk-tag", 
      "total" : 1 
     }, 
     { 
      "tag" : "child", 
      "total" : 1 
     }, 
     { 
      "tag" : "tradeout", 
      "total" : 2 
     }, 
     { 
      "tag" : "adult", 
      "total" : 1 
     } 
    ], 
    "total" : 5 
} 

编辑:

我刚刚注意到,在结果总被计数标签总数,而不是具有至少一个活动标签的文档数量。这个查询会给你想要的确切输出,虽然稍微复杂一点:

db.User.aggregate([ 
    /* unwind so we can process each tag from the array */ 
    { $unwind : "$tags"}, 
    /* Remove the active/inactive strings from the tag values 
     and create a new value tagType */ 
    { $project : { 
     tagType : { 
      $cond : { 
       if : { $eq : [ { $substr : [ "$tags", 0, 6] }, "active" ]}, 
       then: "active", 
       else: "inactive"} 
     }, 
     tag: { 
      $cond : { 
       if : { $eq : [ { $substr : [ "$tags", 0, 6] }, "active" ]}, 
       then: { $substr : ["$tags", 7, -1]}, 
       else: { $substr : ["$tags", 9, -1]}} 
     } 
    }}, 
    /* Group the documents by tag type, so we can 
     find num. of docs by tag type (total) */ 
    { $group : { _id : "$tagType", 
       tags :{ $push : "$tag"}, 
       docId :{ $addToSet : "$_id"}}}, 
    /* project the values so we can get the 'total' for tag type */ 
    { $project : { tagType : "$_id", 
        tags : 1, 
        "docTotal": { $size : "$docId" }}}, 
    /* we must unwind to get total count for each tag */ 
    { $unwind : "$tags"}, 
    /* sum the tags by type and tag value */ 
    { $group : { _id : {tagType : "$tagType", tag: "$tags"} , 
       total: { $sum: 1}, docTotal: {$first : "$docTotal"}}}, 
    /* finally group by tagType so we can get subtags */ 
    { $group : { _id : "$_id.tagType", 
       subtags: { $push : {tag : "$_id.tag", total: "$total"}}, 
       total: { $first : "$docTotal"}}} 
]); 
+0

Ahh我看到了,所以不可能在未知数量的根标签(即'active','active2')上运行这个操作。这不是一个更重要的问题。 –

+0

应该注意的是,这需要'MongoDB 2.6 +' –

+0

>我刚刚注意到结果中的总数是计算标签总数而不是文档数 其实我正在寻找具有根标签和子标签。 –