I've taken a look at this and have been able to reproduce the same problem. Everything is fine for outcomes in the current interaction, but previous interactions aren't behaving as expected.
After digging into it, it's actually due to a bug in Sitecore that has been there since these conditions were first introduced in Sitecore 8.1, and is still present in the initial release of Sitecore 9.0.
The bug
The error lays within the FilterKeyBehaviorCacheEntriesByInteractionConditions
method of the HasEventOccurredCondition<T>
abstract base class that these conditions use, which you can see by decompiling the Sitecore.Analytics
assembly:
if (ConditionsUtility.GetInt32Comparer(this.NumberOfElapsedDaysOperatorId) == null)
return Enumerable.Empty<KeyBehaviorCacheEntry>();
Func<int, int, bool> numberOfPastInteractionsComparer = ConditionsUtility.GetInt32Comparer(this.NumberOfPastInteractionsOperatorId);
if (numberOfPastInteractionsComparer == null)
return Enumerable.Empty<KeyBehaviorCacheEntry>();
// ... some code removed ...
if (numberOfPastInteractionsComparer((DateTime.UtcNow - entries.Key.InteractionStartDateTime).Days, this.NumberOfElapsedDays))
return numberOfPastInteractionsComparer(i + 2, this.NumberOfPastInteractions);
As you can see from the above code, a function is never defined that uses NumberOfElapsedDaysOperatorId
. At the end of the code, the numberOfPastInteractionsComparer
function is actually used for both the elapsed days and past interactions comparisons.
So to use your example:
where the name-of-my-outcome
outcome was registered during a past or current interaction and when the number of elapsed days is less than 30
and when the past number of interactions is not equal to 0
This means that the is less than
operator is never used, and instead is not equal
is used for both operations. This explains why your two examples that used is not equal
worked as expected.
Fix
Until this is fixed, you can workaround this by decompiling and reimplementing the conditions and their base condition, in this case Sitecore.Analytics.Rules.Conditions.OutcomeWasRegisteredDuringPastOrCurrentInteractionCondition
and Sitecore.Analytics.Rules.Conditions.HasEventOccurredCondition<>
. The new base condition should have the method altered like so:
Func<int, int, bool> numberOfElapsedDaysComparer = ConditionsUtility.GetInt32Comparer(NumberOfElapsedDaysOperatorId);
if (numberOfElapsedDaysComparer == null)
return Enumerable.Empty<KeyBehaviorCacheEntry>();
Func<int, int, bool> numberOfPastInteractionsComparer = ConditionsUtility.GetInt32Comparer(this.NumberOfPastInteractionsOperatorId);
if (numberOfPastInteractionsComparer == null)
return Enumerable.Empty<KeyBehaviorCacheEntry>();
// ... some code removed ...
if (numberOfElapsedDaysComparer((DateTime.UtcNow - entries.Key.InteractionStartDateTime).Days, this.NumberOfElapsedDays))
return numberOfPastInteractionsComparer(i + 2, this.NumberOfPastInteractions);
Once you have created these, you would then need to set the Type
field to your new type in the existing Sitecore condition, i.e. /sitecore/system/Settings/Rules/Definitions/Elements/Visit/Outcome was registered during a past or current interaction
.
Notes
It's worth noting that the buggy HasEventOccurredCondition<>
is derived by the following conditions, so these will all exhibit the same fault and would also need to be patched to work correctly:
CampaignWasTriggeredPastOrCurrentInteractionCondition
ChannelOfPastOrCurrentInteractionCondition
GoalWasTriggeredDuringPastOrCurrentInteractionCondition
OutcomeWasRegisteredDuringPastOrCurrentInteractionCondition
PageEventWasTriggeredDuringPastOrCurrentInteractionCondition
VenueOfPastOrCurrentInteractionCondition
These all have slight variants too that allow for Custom Data to be taken into account that will have the same issue.