Thursday, December 7, 2023

seperating the internal traffic in sitecore dashboard experience analytics


Add following facets on the Databases:

1) Core Database

Create a new type Traffic as remaining types defined in sitecore.with the template
/sitecore/client/Speak/Templates/Pages/Speak-DashboardPage



1) PageSettings(/sitecore/client/Speak/Templates/Pages/PageSettings)
copy devices pagesttings(/sitecore/client/Applications/ExperienceAnalytics/Dashboard/Audience/Devices/PageSettings) and rename to traffic type create as below

ExperienceAnalytics Stylesheet(/sitecore/client/Speak/Templates/Pages/Page-Stylesheet-File) same as remaining exp analytics stylesheet


2) Master Database

create a visit type under the /sitecore/system/Marketing Control Panel/Experience Analytics/Dimensions/Visits as By Traffic template(/sitecore/templates/System/Experience Analytics/Dimension)

and Create a  segment name All visits by traffic with the below template

/sitecore/templates/System/Experience Analytics/Segment



create a cshrap code as below

using Sitecore.Analytics;
using Sitecore.Analytics.Aggregation.Data.Model;
using Sitecore.ExperienceAnalytics.Aggregation.Dimensions;
using System;

namespace Domain.Infrastructure.Analytics
{
  public class ByTraffic : VisitDimensionBase
  {
    public ByTraffic(Guid dimensionId) : base(dimensionId)
    {

    }
    public override bool HasDimensionKey(IVisitAggregationContext context)
    {
      return context.Visit.Ip.Length > 0;
    }

    public override string GetKey(IVisitAggregationContext context)
    {
      if ((Tracker.Current.Session.Interaction.Ip.GetValue(0).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(1).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(2).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(3).ToString() == "some ip"))
      {
        return "Dynatrace Portal";
      }
      else if ((Tracker.Current.Session.Interaction.Ip.GetValue(0).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(1).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(2).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(3).ToString() == "some ip")
        || (Tracker.Current.Session.Interaction.Ip.GetValue(0).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(1).ToString() == "some ip"))
      {
        return "Dynatrace Synthetic Monitors";
      }
      else if ((Tracker.Current.Session.Interaction.Ip.GetValue(0).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(1).ToString() == "some ip")
      || (Tracker.Current.Session.Interaction.Ip.GetValue(0).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(1).ToString() == "some ip" && Tracker.Current.Session.Interaction.Ip.GetValue(2).ToString() == "some ip")
      || (Tracker.Current.Session.Interaction.Ip.GetValue(0).ToString() == "207" && Tracker.Current.Session.Interaction.Ip.GetValue(1).ToString() == "211" && Tracker.Current.Session.Interaction.Ip.GetValue(2).ToString() == "37" && Tracker.Current.Session.Interaction.Ip.GetValue(3).ToString() == "4")
      || (Tracker.Current.Session.Interaction.Ip.GetValue(0).ToString() == "10")
      || (Tracker.Current.Session.Interaction.Ip.GetValue(0).ToString() == "127" && Tracker.Current.Session.Interaction.Ip.GetValue(1).ToString() == "0" && Tracker.Current.Session.Interaction.Ip.GetValue(2).ToString() == "0" && Tracker.Current.Session.Interaction.Ip.GetValue(3).ToString() == "1"))
      {
        return "Internal Public IP";
      }

      return "External";
    }
  }
}

add add a below patch config

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <experienceAnalytics>
      <api enabled="true">
        <dimensions>
          <dimension id="ByTraffic ID from Master db">
            <transformer type="Sitecore.ExperienceAnalytics.Api.Response.DimensionKeyTransformers.DefaultDimensionKeyTransformer, Sitecore.ExperienceAnalytics.Api"/>
          </dimension>
        </dimensions>
      </api>
      <reduce>
        <dimensions>
          <dimension id="ByTraffic ID from Master db" type="Domain.Infrastructure.Analytics.ByTraffic, Domain.Infrastructure" />
        </dimensions>
      </reduce>
      <aggregation>
        <dimensions>
          <dimension id="ByTraffic ID from Master db" type="Domain.Infrastructure.Analytics.ByTraffic, Domain.Infrastructure" />
        </dimensions>
      </aggregation>
    </experienceAnalytics>
  </sitecore>
</configuration>

result:



Implementing solr search using the sitecore default sort.

As the sort order field isn't returned by default the best way to handle this is to add a add a new computed field to the index. This will then be available to query by in Solr.
1. Computed Index Field
Create this class within your Sitecore project:
    public class SortOrderField : IComputedIndexField
    {
        public object ComputeFieldValue(IIndexable indexable)
        {
            int DefaultSortOrderValue = 0;

            var item = (Item)(indexable as SitecoreIndexableItem);
            if (item == null) return null;

            if (string.IsNullOrEmpty(item[Sitecore.FieldIDs.Sortorder]))
            {
                return DefaultSortOrderValue;
            }

            int sortOrder;
            return int.TryParse(item[Sitecore.FieldIDs.Sortorder], out sortOrder)
                ? sortOrder
                : DefaultSortOrderValue;
        }

        public string FieldName { get; set; }

        public string ReturnType { get; set; }
    }
2. Config for Computed Field
Add this config patch file (or merge it into an existing search patch file):
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <contentSearch>
            <indexConfigurations>
                <defaultSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">
                    <fields hint="raw:AddComputedIndexField">
                        <field fieldName="sortorder" returnType="int">MyCustom.Search.Indexing.SortOrderField, MyCustom.Search</field>
                    </fields>
            </indexConfigurations>
        </contentSearch>
    </sitecore>
</configuration>
3. Search Result Item Model
Add the sort order into either your base Search Result Item model so it's available for all search result types or a specific model like so:
public class ContentSearchItem : SearchResultItem
    {
        [IndexField("_displayname")]
        public string DisplayName { get; set; }

        [IndexField("__smallupdateddate")]
        public DateTime LastUpdated { get; set; }

        [IndexField("sortorder")]
        public int SortOrder { get; set; }
    }
4. Update you search query
You should now be able to update your search query to include the ordering by sortorder like so:
using (var context = ContentSearchManager.CreateSearchContext((SitecoreIndexableItem) indexItem))
    {
        var searchResultItems = context.GetQueryable<ContentSearchItem>()
            .OrderBy(x => x.SortOrder)
}
5. Rebuild your indexes
You will need to re-build your web index (and master if you want to see the changes on CA) in order for the new sortorder field to show up in the index. You may also need to re-order content in Content Editor so that the sortorder field value is set (or perhaps use Sitecore Powershell to do this for you).
There is more info here and additional steps you may need to carry out depending on your situation (thanks to Marta Imos-Merska for her post):