2017-10-17 254 views
0

我已经在MongoDB的外壳做得到每种类型每个用户的警报的数量以下聚合:如何在Spring MongoDB聚合上使用项目DBRef?

db.getCollection('alerts').aggregate(

     { 
      $unwind:"$son" 
     }, 
     { 
      $group: 
      { 
       _id:{ 
        son: "$son", 
        level: "$level" 
       }, 
       count: { $sum: 1 } 
      } 
     }, 
     { 
      $group: 
       { 
        _id:{ 
         son: "$_id.son" 
        }, 
        alerts: { $addToSet: { 
         level: "$_id.level", 
         count: "$count" 
        }} 

       } 
     } 
     ) 

我把它翻译成春数据的MongoDB如下:

TypedAggregation<AlertEntity> alertsAggregation = 
       Aggregation.newAggregation(AlertEntity.class, 
         unwind("$son"), 
         Aggregation.group("$son", "$level").count().as("count"), 
         Aggregation.group("$_id.son") 
          .addToSet(new BasicDBObject("level", "$_id.level").append("count", "$count")).as("alerts")); 

     // Aggregation.match(Criteria.where("_id").in(sonIds) 

      AggregationResults<AlertsBySonDTO> results = mongoTemplate. 
       aggregate(alertsAggregation, AlertsBySonDTO.class); 

      List<AlertsBySonDTO> alertsBySonResultsList = results.getMappedResults(); 

      return alertsBySonResultsList; 

我不清楚,但我不能得到它的工作,是投影标识符,如果可能的话,用户的名称(儿子变量)。

The resulting DTO is as follows 


public final class AlertsBySonDTO implements Serializable { 

    private static final long serialVersionUID = 1L; 


    @JsonProperty("identity") 
    private String id; 

    @JsonProperty("alerts") 
    private ArrayList<Map<String, String>> alerts; 

} 

但在id属性中的整个嵌入子实体。

这是警报集合的结构。

enter image description here

JSON格式提醒:

{ 
    "_id" : ObjectId("59e6ff3d9ef9d46a91112890"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "INFO", 
    "title" : "Alerta de Prueba", 
    "payload" : "Alerta de Prueba", 
    "create_at" : ISODate("2017-10-18T07:13:45.091Z"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : { 
     "$ref" : "parents", 
     "$id" : ObjectId("59e6ff369ef9d46a91112878") 
    }, 
    "son" : { 
     "$ref" : "children", 
     "$id" : ObjectId("59e6ff389ef9d46a9111287b") 
    } 
} 

/* 2 */ 
{ 
    "_id" : ObjectId("59e6ff6d9ef9d46a91112892"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "WARNING", 
    "title" : "Token de acceso inv�lido.", 
    "payload" : "El token de acceso YOUTUBE no es v�lido", 
    "create_at" : ISODate("2017-10-18T07:14:53.449Z"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : { 
     "$ref" : "parents", 
     "$id" : ObjectId("59e6ff369ef9d46a91112878") 
    }, 
    "son" : { 
     "$ref" : "children", 
     "$id" : ObjectId("59e6ff389ef9d46a9111287b") 
    } 
} 

/* 3 */ 
{ 
    "_id" : ObjectId("59e6ff6d9ef9d46a91112893"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "WARNING", 
    "title" : "Token de acceso inv�lido.", 
    "payload" : "El token de acceso INSTAGRAM no es v�lido", 
    "create_at" : ISODate("2017-10-18T07:14:53.468Z"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : { 
     "$ref" : "parents", 
     "$id" : ObjectId("59e6ff369ef9d46a91112878") 
    }, 
    "son" : { 
     "$ref" : "children", 
     "$id" : ObjectId("59e6ff389ef9d46a9111287c") 
    } 
} 

任何人都知道我该怎么处理这个?

在此先感谢

+0

你可以粘贴一个json警报集合的例子吗? –

+0

从粘贴的图像我看不出儿子是一个数组,因为在你的聚合中,你正在展开。粘贴json而不是图片会更好。 –

+0

我并没有真正掌握MongoDB中的聚合,它是获得我想要的结果的唯一方法。但我的问题更多集中在投影的最后部分。我无法获取DBRef字段的ID。 –

回答

2

1. MongoDB的3.4版

这些是以下集合,我创建重现你的使用情况:

警报收集

{ 
    "_id" : ObjectId("59e6ff3d9ef9d46a91112890"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "INFO", 
    "title" : "Alerta de Prueba", 
    "payload" : "Alerta de Prueba", 
    "create_at" : ISODate("2017-10-18T07:13:45.091+0000"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : DBRef("parents", ObjectId("59e6ff369ef9d46a91112878")), 
    "son" : DBRef("children", ObjectId("59e72ff0572ae72d8c063666")) 
} 
{ 
    "_id" : ObjectId("59e6ff6d9ef9d46a91112892"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "WARNING", 
    "title" : "Token de acceso inv�lido.", 
    "payload" : "El token de acceso YOUTUBE no es valido", 
    "create_at" : ISODate("2017-10-18T07:14:53.449+0000"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : DBRef("parents", ObjectId("59e6ff369ef9d46a91112878")), 
    "son" : DBRef("children", ObjectId("59e72ff0572ae72d8c063666")) 
} 
{ 
    "_id" : ObjectId("59e6ff6d9ef9d46a91112893"), 
    "_class" : "es.bisite.usal.bulltect.persistence.entity.AlertEntity", 
    "level" : "WARNING", 
    "title" : "Token de acceso inv�lido.", 
    "payload" : "El token de acceso INSTAGRAM no es v�lido", 
    "create_at" : ISODate("2017-10-18T07:14:53.468+0000"), 
    "delivery_mode" : "PUSH_NOTIFICATION", 
    "delivered" : false, 
    "parent" : DBRef("parents", ObjectId("59e6ff369ef9d46a91112878")), 
    "son" : DBRef("children", ObjectId("59e72ffb572ae72d8c063669")) 
} 

注意我更改了儿子参考的OBjectIds以符合我创建的儿童收藏。

Children集合

{ 
    "_id" : ObjectId("59e72ff0572ae72d8c063666"), 
    "name" : "Bob" 
} 
{ 
    "_id" : ObjectId("59e72ffb572ae72d8c063669"), 
    "name" : "Tim" 
} 

由于您使用的一个参考,你不能只是从其他集合访问的字段。所以我认为你错过了一些聚合步骤。

我做了以下内容:

db.getCollection('alerts').aggregate(
{ 
      $unwind:"$son" 
     }, 
     { 
      $group: 
      { 
       _id:{ 
        son: "$son", 
        level: "$level" 
       }, 
       count: { $sum: 1 } 
      } 
     }, 
     { 
      $group: 
       { 
        _id:{ 
         son: "$_id.son" 
        }, 
        alerts: { $addToSet: { 
         level: "$_id.level", 
         count: "$count" 
        }} 

       } 
     }, 
     { $addFields: { sonsArray: { $objectToArray: "$_id.son" } } }, 
     { $match: { "sonsArray.k": "$id"} }, 
     { $lookup: { from: "children", localField: "sonsArray.v", foreignField: "_id", as: "name" } } 
) 

,并得到了以下结果为JSON:

{ 
    "_id" : { 
     "son" : DBRef("children", ObjectId("59e72ffb572ae72d8c063669")) 
    }, 
    "alerts" : [ 
     { 
      "level" : "WARNING", 
      "count" : NumberInt(1) 
     } 
    ], 
    "sonsArray" : [ 
     { 
      "k" : "$ref", 
      "v" : "children" 
     }, 
     { 
      "k" : "$id", 
      "v" : ObjectId("59e72ffb572ae72d8c063669") 
     } 
    ], 
    "name" : [ 
     { 
      "_id" : ObjectId("59e72ffb572ae72d8c063669"), 
      "name" : "Tim" 
     } 
    ] 
} 
{ 
    "_id" : { 
     "son" : DBRef("children", ObjectId("59e72ff0572ae72d8c063666")) 
    }, 
    "alerts" : [ 
     { 
      "level" : "INFO", 
      "count" : NumberInt(1) 
     }, 
     { 
      "level" : "WARNING", 
      "count" : NumberInt(1) 
     } 
    ], 
    "sonsArray" : [ 
     { 
      "k" : "$ref", 
      "v" : "children" 
     }, 
     { 
      "k" : "$id", 
      "v" : ObjectId("59e72ff0572ae72d8c063666") 
     } 
    ], 
    "name" : [ 
     { 
      "_id" : ObjectId("59e72ff0572ae72d8c063666"), 
      "name" : "Bob" 
     } 
    ] 
} 

如果你想摆脱这其中另外像sonsArray等,您可以创建字段请添加$project管道到clean您的结果。


2.如果你有旧版本的MongoDB,你可以改变你的数据结构。

相反,如果使用这样的参考:

"sonId" : [ 
     ObjectId("59e72ff0572ae72d8c063666") 
    ] 

那么你可以做你的聚集:

"son" : DBRef("children", ObjectId("59e72ffb572ae72d8c063669")) 

,你可以像这样的数组添加儿子/秒的OBJECTID如下:

db.getCollection('alerts').aggregate(
{ 
      $unwind:"$sonId" 
     }, 
     { 
      $group: 
      { 
       _id:{ 
        sonId: "$sonId", 
        level: "$level" 
       }, 
       count: { $sum: 1 } 
      } 
     }, 
     { 
      $group: 
       { 
        _id:{ 
         sonId: "$_id.sonId" 
        }, 
        alerts: { $addToSet: { 
         level: "$_id.level", 
         count: "$count" 
        }} 

       } 
     }, 
     { $lookup: { from: "children", localField: "_id.sonId", foreignField: "_id", as: "son" } } 
) 

这是你正在寻找的东西?

+0

这很完美,问题在于我无法使用最近版本的mongodb。显然这个阶段“$ addFields”是在3.4版本中添加的。以前的版本可以做不同的事情吗? –

+0

恐怕这是不可能的,因为即使我为“$ addFields”提供了一个替代方案(例如将其替换为更长的“$ project”阶段),您也会遇到下一个“ $ objectToArray”。这也仅适用于3.4。也许这就足以升级到最新的mongo版本。如果您可以灵活地更改架构,它只能与3.2一起工作。 –

+0

如果你有兴趣改变你的模式,我可以详细说明一下。 –