Is it possible to remove the pattern cards matched in sitecore by the current user when he navigates back to a specific page programmatically?
Just want to have an idea on how to do this.
Thank you in advance.
Sitecore Stack Exchange is a question and answer site for developers and end users of the Sitecore CMS and multichannel marketing software. It only takes a minute to sign up.
Sign up to join this communityNo - there is no way to remove a Pattern matched by the current visitor when the visitor navigates back to a specific page.
Pattern matching is based on Euclidean Distance across vectors. This means that Sitecore calculates the pattern that a visitor matches by taking all of the possible patterns, using their configured profile key scores as vectors, using the visitor's interaction scores as vectors, and then deducing which pattern vector has the shortest distance (i.e. is the most similar) to visitor's interaction vector.
In English, this means that Sitecore looks at the visitor's scores, as accumulated from the visitor's interactions with the site, and finds the pattern with the scores that are most similar (often most proportionate).
Because the matched pattern is always the pattern with the most similar scores to the visitor's interactions, the only way to disassociate a visitor from a pattern is to change the visitor's interaction scores. You have to do this manually, if it is really something that you want to do, and there's no way to really guarantee accuracy, as the computation is based entirely on computing the smallest distance between two vectors.
Think of it this way: assume that you have a visitor with a bunch of scores for a profile, and that the visitor currently matches the Foo pattern. You have an item reference to the Foo pattern (assume from configs or something like that) and you can see what profile key scores are configured for it. How would you remove this pattern from the user? You can remove all of the scores for which the Foo pattern has points, but then you might remove scores for other patterns, as well. You could try removing scores proportionate to Foo's scores in a loop until the visitor no longer matches Foo, but then you may, again, remove scores for other patterns. No matter what you do, here, there is no way to guarantee that you are removing the pattern match from the visitor without affecting other patterns.
There are two ways to change scores: by increasing them or by decreasing them. It would be very difficult (and bad for performance) to try to accurately roll a visitor back to a specific pattern, but you could back a visitor's scores from specific interactions.
If you store the profile and score values that were associated with each interaction and you know the interaction that you want to roll back to then you should be able to simply roll back all of the scores that were added after that point.
I do not recommend that you roll back scores or interactions, under any circumstances. When you do that, you are taking good analytics data and tainting it and/or throwing it out, programmatically.
I have had clients and UX team members ask me about doing things like this and it has been my experience that each time they are just trying to use the wrong tool for the job.
If the goal is to personalize and always show the same personalized content to the visitor when they navigate back to the page then add a custom rule for that in Sitecore. Store on the visitor's profile or in session (depending on long-term vs. short term), etc. a value that indicates which rendering you showed previously and add the custom logic to show it on repeat visits before attempting to render the personalized component (you can do this via pipelines or code in your controllers - I recommend pipelines over controllers).
In Sitecore, there is currently no concept of "exclusion" with regard to pattern matches for a specific visitor. In other words, there is no way to do something like the following, given that you want to update the visitor to match the closest pattern that is not the Foo pattern:
profile.UpdatePattern(excludedPatterns: new [] { "Foo" });
Conceptually, what the above code would (ideally) do is compute the Euclidean Distance between the visitor's profile, profile
, and each of the patterns except for the Foo pattern. This way, analytics data would not have to be modified and you could still ensure that the visitor doesn't match a specific pattern when navigating back to a given page.
Before writing this post, I took a look inside the decompiled Sitecore.Analytics assemblies in order to see how difficult it would be to add support for these computations yourself. The answer is that it would be very high effort and risk. You would have to rewrite some pretty large pieces of Sitecore.Analytics in order to do this, so my recommendation is that you instead open a support ticket and request that this feature be added to a future release of Sitecore.
In the solution that @HishaamNamooya posted, he advises that you delete the Interaction records and the Behavior Profiles in order to delete the pattern. That code will do what you are looking for in the same way that an elephant gun can be used to kill a mouse...you'll be doing a lot more damage than you probably intended.
Deleting the interaction records and behavior profiles will remove the Pattern, but it will also obliterate all scores and interactions that the visitor has had with the site in their behavior profiles, and all scores and interactions from the current visit within the profile that contains the pattern you are trying to remove. Effectively, you're throwing out other good data that you probably don't mean to get rid of.
Consider that you have configured a Profile in Sitecore, named Cars (going to go somewhat 2D, here, for Simplicity's sake). The Cars profile has the following profile keys:
When a visitor clicks on one of your pages, that page has scores for each of those profile keys that are proportional to how likely the key is to be "important" to the user.
Additionally, assume that you have the following Patterns configured for the Cars profile (generally, I try to go more abstract with pattern names, but the below is meant for demonstration):
Assume that you have a visitor who browses to a few pages that indicate that they are interested the outdoors and family. Right now, this visitor matches the All-Terrain pattern the closest. The visitor then navigates to a few other pages, indicating a strong interest in manual labor (construction, carpentry, etc.). With this new information added to the visitor's scores, the visitor now matches the Pickup pattern the closest.
Now consider that our site should implement logic as described in the OP. When the visitor navigates back to some specific page, Foo, the visitor's match with the Pickup pattern should be removed. Implicitly, the result is that the visitor should once again be matched with the All-Terrain pattern.
If you achieve this logic by deleting all of the interaction records and behavior profiles then the results will not be as expected. What will actually happen is that you will be erasing everything that you currently know about the user and their interactions, as they relate to the "Cars" profile, including all of their interactions that led up to the match with the All-Terrain pattern, as well as the Pickup pattern. You would be throwing out good data and there would be no way to distinguish between data that matches the Pickup pattern vs data that matches the All-Terrain pattern.
What you likely want to do instead is remember the pattern that a visitor had on the specific page. Once you have that, you can work from there to manually override your personalization flow (my recommendation is to do this through a pipeline) to use the stored pattern rather than the visitor's current pattern.
In a situation like this, you could even leverage Sitecore Caching, though I don't recommend that you rely on this alone. If you set your rendering caching options to Vary By User, then the rendered output that was first displayed to the user will be the output that is "always" (until the cache clears) shown to the user. Again, I don't recommend that you solely rely on Sitecore Caching, but if that is the general logic that you're looking to implement then that should point you in the right direction.
While Hishaam's solution is more of a blunt object, there really isn't a scalpel that will get you what you want. Regardless, I believe that deleting interactions and behavior profiles is typically a far more drastic solution than what is needed, and will have repercussions that you may not be willing to accept.
My recommendation is that you take a hard look at what you are trying to accomplish and find a different and better way to do so. Ask yourself what it is that you're actually trying to implement and accomplish and then ask the community. I recommend, asking your question in the #sitecore-chat channel of the Sitecore Community Slack to see if other developers and MVPs can help you to brainstorm alternatives. Feel free to direct message me @zachary_kniebel too, if you just want to talk through your thoughts, needs or implementation.
You need to remove the Pattern from both Interaction and BehaviorProfiles. When the user enters the specific page, you need to trigger the methods below.
Remove from the Interaction
Tracker.Current.Interaction.Profiles.Remove("Your Profile Name");
Remove from Behavioral Profile
private static void UpdateBehaviorProfile(Session session)
{
var profileConverterBase = BehaviorProfileConverterBase.Create();
if (session?.Contact == null || Tracker.Current.Interaction == null)
{
return;
}
session.Contact.BehaviorProfiles.RemoveAll();
foreach (var profileName in session.Interaction.Profiles.GetProfileNames())
{
var profile = session.Interaction.Profiles[profileName];
if (!IgnoreInteractionProfile(profile))
{
var matchedBehaviorProfile = profileConverterBase.Convert(profile);
session.Contact.BehaviorProfiles.Add(matchedBehaviorProfile.Id, matchedBehaviorProfile);
}
}
}
private static bool IgnoreInteractionProfile(Profile profile)
{
Assert.ArgumentNotNull(profile, "profile");
// Logic goes here whether to add the profile to the contact behavior or not
return false;
}
Warning
Point to note here is that when removing the pattern from the user profile interaction and behavior, you'll no longer be able to have the values again as it will remove it completely.