in services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java [796:869]
private void recalculatePastEventOccurrencesOnProfiles(Condition eventCondition, Condition parentCondition,
boolean forceRefresh, boolean resetExistingProfilesNotMatching) {
long t = System.currentTimeMillis();
List<Condition> l = new ArrayList<>();
Condition andCondition = new Condition();
andCondition.setConditionType(definitionsService.getConditionType("booleanCondition"));
andCondition.setParameter("operator", "and");
andCondition.setParameter("subConditions", l);
l.add(eventCondition);
Integer numberOfDays = (Integer) parentCondition.getParameter("numberOfDays");
String fromDate = (String) parentCondition.getParameter("fromDate");
String toDate = (String) parentCondition.getParameter("toDate");
if (numberOfDays != null) {
Condition numberOfDaysCondition = new Condition();
numberOfDaysCondition.setConditionType(definitionsService.getConditionType("sessionPropertyCondition"));
numberOfDaysCondition.setParameter("propertyName", "timeStamp");
numberOfDaysCondition.setParameter("comparisonOperator", "greaterThan");
numberOfDaysCondition.setParameter("propertyValue", "now-" + numberOfDays + "d");
l.add(numberOfDaysCondition);
}
if (fromDate != null) {
Condition startDateCondition = new Condition();
startDateCondition.setConditionType(definitionsService.getConditionType("sessionPropertyCondition"));
startDateCondition.setParameter("propertyName", "timeStamp");
startDateCondition.setParameter("comparisonOperator", "greaterThanOrEqualTo");
startDateCondition.setParameter("propertyValueDate", fromDate);
l.add(startDateCondition);
}
if (toDate != null) {
Condition endDateCondition = new Condition();
endDateCondition.setConditionType(definitionsService.getConditionType("sessionPropertyCondition"));
endDateCondition.setParameter("propertyName", "timeStamp");
endDateCondition.setParameter("comparisonOperator", "lessThanOrEqualTo");
endDateCondition.setParameter("propertyValueDate", toDate);
l.add(endDateCondition);
}
String propertyKey = (String) parentCondition.getParameter("generatedPropertyKey");
Set<String> existingProfilesWithCounts = resetExistingProfilesNotMatching ? getExistingProfilesWithPastEventOccurrenceCount(propertyKey) : Collections.emptySet();
int updatedProfileCount = 0;
if (pastEventsDisablePartitions) {
Map<String, Long> eventCountByProfile = persistenceService.aggregateWithOptimizedQuery(eventCondition, new TermsAggregate("profileId"), Event.ITEM_TYPE, maximumIdsQueryCount);
Set<String> updatedProfiles = updatePastEventOccurrencesOnProfiles(eventCountByProfile, propertyKey);
existingProfilesWithCounts.removeAll(updatedProfiles);
updatedProfileCount = updatedProfiles.size();
} else {
Map<String, Double> m = persistenceService.getSingleValuesMetrics(andCondition, new String[]{"card"}, "profileId.keyword", Event.ITEM_TYPE);
long card = m.get("_card").longValue();
int numParts = (int) (card / aggregateQueryBucketSize) + 2;
for (int i = 0; i < numParts; i++) {
Map<String, Long> eventCountByProfile = persistenceService.aggregateWithOptimizedQuery(andCondition, new TermsAggregate("profileId", i, numParts), Event.ITEM_TYPE);
Set<String> updatedProfiles = updatePastEventOccurrencesOnProfiles(eventCountByProfile, propertyKey);
existingProfilesWithCounts.removeAll(updatedProfiles);
updatedProfileCount += updatedProfiles.size();
}
}
// remaining existing profiles with counts should be reset to 0 since they have not been updated it means
// that they do not have matching events anymore in the time based condition
if (!existingProfilesWithCounts.isEmpty()) {
updatedProfileCount += updatePastEventOccurrencesOnProfiles(
existingProfilesWithCounts.stream().collect(Collectors.toMap(key -> key, value -> 0L)), propertyKey).size();
}
if (forceRefresh && updatedProfileCount > 0) {
persistenceService.refreshIndex(Profile.class);
}
LOGGER.info("{} profiles updated for past event condition in {}ms", updatedProfileCount, System.currentTimeMillis() - t);
}