private void doReduce(List<Tuple2<String, Integer>> collect) {
    logger.debug("come into doReduce -->");
    Map<String, Document> cacheMap = new HashMap<String, Document>();
    for (Tuple2<String, Integer> tuple : collect) {
      if (!tuple._1().startsWith("EventDetailInfo")) {
        continue;
      }
      // 缓存汇总结果
      doCacheEventDetailInfo(cacheMap, tuple);
    }
    Set<String> keys = cacheMap.keySet();
    for (String keyStr : keys) {
      String key[] = keyStr.split(":");
      String tableName = key[0];
      Document eventDetailInfoDoc = cacheMap.get(keyStr);

      // 保存汇总结果到mongoDb
      eventDetailInfoDao.saveOrUpdate(tableName, eventDetailInfoDoc);
    }
  }
  /**
   * 缓存每条汇总结果
   *
   * @param cacheMap
   * @param tuple
   */
  private void doCacheEventDetailInfo(
      Map<String, Document> cacheMap, Tuple2<String, Integer> tuple) {
    logger.debug("come into doCacheEventDetailInfo ==> " + tuple._1() + " <--> " + tuple._2());
    // 解析表名:字段名:timeValue:appId:appVersion:appChannel:appPlatform:eventId:paramKey:paramValue(tenantId)
    String keys[] = tuple._1().split(":");
    String tableName = keys[0];
    String fieldName = keys[1];
    String timeValue = keys[2];
    String appId = keys[3];
    String appVersion = keys[4];
    String appChannel = keys[5];
    String appPlatform = keys[6];
    String eventId = keys[7];
    String paramKey = keys[8];
    String paramValue = keys[9];
    String tenantId =
        (keys.length == 11 && keys[10] != null && !keys[10].trim().isEmpty()) ? (keys[10]) : "";
    String tenantIdKey =
        (keys.length == 11 && keys[10] != null && !keys[10].trim().isEmpty())
            ? (":" + keys[10])
            : ""; // 存在tenantId就加到keyStr中去

    Document eventDetailInfoDoc = null;

    String keyStr =
        tableName
            + ":"
            + timeValue
            + ":"
            + appId
            + ":"
            + appVersion
            + ":"
            + appChannel
            + ":"
            + appPlatform
            + ":"
            + eventId
            + ":"
            + paramKey
            + ":"
            + paramValue
            + tenantIdKey;
    // 如果缓存命中,使用缓存的对象
    if (cacheMap.containsKey(keyStr)) {
      eventDetailInfoDoc = cacheMap.get(keyStr);
    } else {
      eventDetailInfoDoc =
          eventDetailInfoDao.findOneBy(
              tableName,
              timeValue,
              appId,
              appVersion,
              appChannel,
              appPlatform,
              eventId,
              paramKey,
              paramValue,
              tenantId);
    }

    if (eventDetailInfoDoc == null) {
      EventDetailInfo eventDetailInfoTemp = new EventDetailInfo();
      eventDetailInfoTemp.setEventId(eventId);
      eventDetailInfoTemp.setTimeValue(timeValue);
      eventDetailInfoTemp.setAppId(appId);
      if (tenantId != null && !tenantId.trim().isEmpty()) {
        eventDetailInfoTemp.setTenantId(tenantId);
      }
      Gson gson = new Gson();
      eventDetailInfoDoc = Document.parse(gson.toJson(eventDetailInfoTemp));
      ObjectId objId = new ObjectId();
      eventDetailInfoDoc.put("_id", objId);
      eventDetailInfoDoc.put("appVersion", appVersion);
      eventDetailInfoDoc.put("appChannel", appChannel);
      eventDetailInfoDoc.put("appPlatform", appPlatform);
      eventDetailInfoDoc.put("paramKey", paramKey);
      eventDetailInfoDoc.put("paramValue", paramValue);
    }
    if (eventDetailInfoDoc.get(fieldName) == null) {
      eventDetailInfoDoc.put(fieldName, (long) tuple._2());
    } else {
      long fieldValue = 0;
      try {
        fieldValue = eventDetailInfoDoc.getLong(fieldName);
      } catch (ClassCastException e) {
        fieldValue = (long) eventDetailInfoDoc.getInteger(fieldName);
      }
      eventDetailInfoDoc.put(fieldName, (long) (fieldValue + tuple._2()));
    }
    cacheMap.put(keyStr, eventDetailInfoDoc);
    return;
  }