使用Spring MongoDB的嵌套组

时间:2017-10-15 20:27:21

标签: spring mongodb aggregation-framework spring-mongo spring-mongodb

我需要为每个用户生成每个级别的警报数量的结果。

类似于以下的结构:

{
  "identitity": "59e3b9dc5a3254691f327b67",
  "alerts": [
    {
      "level": "INFO",
      "count": "3"
    },
    {
      "level": "ERROR",
      "count": "10"

     } 
  ]

}

警报权限具有以下结构:

@Document(collection = AlertEntity.COLLECTION_NAME)
public class AlertEntity {

    public final static String COLLECTION_NAME = "alerts";

    @Id
    private ObjectId id;

    @Field
    private AlertLevelEnum level = AlertLevelEnum.INFO;

    @Field("title")
    private String title;

    @Field("payload")
    private String payload;

    @Field("create_at")
    private Date createAt = new Date();

    @Field("delivered_at")
    private Date deliveredAt;

    @Field("delivery_mode")
    private AlertDeliveryModeEnum deliveryMode = 
   AlertDeliveryModeEnum.PUSH_NOTIFICATION;

    @Field("parent")
    @DBRef
    private ParentEntity parent;

    @Field("son")
    @DBRef
    private SonEntity son;

    private Boolean delivered = Boolean.FALSE;

}

我已经实现了以下方法,尝试以嵌套方式投影结果。但是"身份"字段始终为空,并且"警告" field是一个空集合。

@Override
    public List<AlertsBySonDTO> getAlertsBySon(List<String> sonIds) {


        TypedAggregation<AlertEntity> alertsAggregation = 
                Aggregation.newAggregation(AlertEntity.class,
                    Aggregation.group("son.id", "level").count().as("count"),
                    Aggregation.project().and("son.id").as("id")
                        .and("alerts").nested(
                                bind("level", "level").and("count")));

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

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

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

            return alertsBySonResultsList;
    }  

我得到的结果如下:

{
  "response_code_name": "ALERTS_BY_SON",
  "response_status": "SUCCESS",
  "response_http_status": "OK",
  "response_info_url": "http://yourAppUrlToDocumentedApiCodes.com/api/support/710",
  "response_data": [
    {
      "identity": null,
      "alerts": []
    },
    {
      "identity": null,
      "alerts": []
    }
  ],
  "response_code": 710
}

结果DTO如下:

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;


    public AlertsBySonDTO() {
        super();
    }

    public AlertsBySonDTO(String id, ArrayList<Map<String, String>> alerts) {
        super();
        this.id = id;
        this.alerts = alerts;
    }



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public ArrayList<Map<String, String>> getAlerts() {
        return alerts;
    }

    public void setAlerts(ArrayList<Map<String, String>> alerts) {
        this.alerts = alerts;
    }
}

以嵌套方式投影结果需要做些什么?

提前致谢

1 个答案:

答案 0 :(得分:1)

在聚合框架中有一个 $unwind 运算符,它基本上将您的一个元素集合与两个元素的嵌套数组转换为两个单独的文档,其中包含此数组中的一个元素。所以你得到:

{
 "identitity": "59e3b9dc5a3254691f327b67",
 "alerts": {
     "level": "INFO",
     "count": "3"
   }

}

{
     "identitity": "59e3b9dc5a3254691f327b67",
     "alerts": {
         "level": "ERROR",
         "count": "10"
     } 
}

这是你可以通过计数开始你的小组的地方。应该工作正常。