Skip to content

Commit 61c9894

Browse files
committed
Update SQL requirements & Code overloads
1 parent 449178b commit 61c9894

File tree

5 files changed

+121
-13
lines changed

5 files changed

+121
-13
lines changed

17/umbraco-engage/developers/personalization/custom-scoring.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ This might be difficult to accomplish through the Content Scoring UI in Umbraco,
1414

1515
To manage scoring for personas, we need to get a reference to `IPersonaService`. For the customer journey, we will need the `ICustomerJourneyService`. Both services can be found under the namespace `Umbraco.Engage.Infrastructure.Personalization.Services`.
1616

17-
To implement our example above, we will be using the `ICustomerJourneyService`. To modify the customer journey step scoring, we need to know the ID of the step we are trying to score. For your implementation you could hardcode the IDs (since they are unlikely to change), we can also fetch them by name through the `ICustomerJourneyGroupRepository`.
17+
Both services support two ways to identify entities:
18+
- **Numeric IDs** (e.g., `personaId`, `customerJourneyStepId`) - Legacy approach using database IDs
19+
- **GUID Keys** (e.g., `personaKey`, `stepKey`) - Preferred approach using Umbraco's GUID-based identifiers
20+
21+
To implement our example above, we will be using the `ICustomerJourneyService`. To modify the customer journey step scoring, we need to know the ID or Key of the step we are trying to score. For your implementation you could hardcode the IDs/Keys (since they are unlikely to change), we can also fetch them by name through the `ICustomerJourneyGroupRepository`.
1822

1923
To resolve the required services, we will use Dependency Injection:
2024

@@ -46,23 +50,28 @@ var stepDo = customerJourneyGroup.Steps.FirstOrDefault(step => step.Title == "Do
4650
```
4751
{% endcode %}
4852

49-
We can now inspect the step **Do** variable and find its `ID`. To score the step, we provide the `ID` and the score to the `CustomerJourneyService`:
53+
We can now inspect the step **Do** variable and find its `Id` or `Key`. To score the step, we provide either the numeric ID or GUID Key and the score to the `CustomerJourneyService`:
5054

5155
```csharp
56+
// Using numeric ID (legacy approach)
5257
_customerJourneyService.ScoreCustomerJourneyStep(stepDo.Id, 100);
58+
59+
// Using GUID Key (preferred approach)
60+
_customerJourneyService.ScoreCustomerJourneyStep(stepDo.Key, 100);
5361
```
5462

5563
We have now added a **score of 100** to the Customer Journey step "**Do**". It is also possible to add negative scores. In our example, we can decrease the scores for "**See**" and "**Think**".
5664

5765
Since the user is no longer (shifting away) from that step of the Customer Journey the implementation strategy is the same for personas.
5866

59-
Another, more advanced, example could be on how to reset the score of a persona for a given visitor. We can use the same approach as above to fetch the **persona** instead of the Customer Journey for the current visitor. We can get the visitor's current score based on the Persona ID, and subtract that exact score from said visitor.
67+
Another, more advanced, example could be on how to reset the score of a persona for a given visitor. We can use the same approach as above to fetch the **persona** instead of the Customer Journey for the current visitor. We can get the visitor's current score based on the Persona ID or Key, and subtract that exact score from said visitor.
6068

6169
{% hint style="info" %}
6270
When scoring outside of a regular HttpContext request (e.g., in background jobs or external integrations), you must use the overload that includes `PersonalizationScoreType`. The `PersonalizationScoreType` enum specifies whether the score is `Implicit` (behavior-based) or `Explicit` (direct assignment).
6371
{% endhint %}
6472

6573
```csharp
74+
// Using numeric ID
6675
public IActionResult ResetPersonaScoreToZero(long personaId)
6776
{
6877
var visitorId = _visitorContext.GetVisitorExternalId();
@@ -81,8 +90,48 @@ public IActionResult ResetPersonaScoreToZero(long personaId)
8190

8291
return Ok("OK");
8392
}
93+
94+
// Using GUID Key (preferred approach)
95+
public IActionResult ResetPersonaScoreToZero(Guid personaKey)
96+
{
97+
var visitorId = _visitorContext.GetVisitorExternalId();
98+
99+
if (visitorId.HasValue)
100+
{
101+
var personaGroups = _personaGroupRepository.GetPersonaScoresByVisitor(visitorId.Value);
102+
var personaGroup = personaGroups.FirstOrDefault(x => x.Personas.Any(y => y.Key == personaKey));
103+
var persona = personaGroup?.Personas.FirstOrDefault(x => x.Key == personaKey);
104+
if (persona != null)
105+
{
106+
_personaService.ScorePersona(visitorId.Value, personaKey, persona.Score * -1, PersonalizationScoreType.Explicit);
107+
return Ok($"Subtracted {persona.Score} from visitor {visitorId}");
108+
}
109+
}
110+
111+
return Ok("OK");
112+
}
84113
```
85114

86115
{% hint style="info" %}
87-
The simpler overloads `ScorePersona(long personaId, int score)` and `ScoreCustomerJourneyStep(long customerJourneyStepId, int score)` should only be used within the context of a regular HttpContext request, as they automatically resolve the current visitor.
116+
The simpler overloads `ScorePersona(long personaId, int score)`, `ScorePersona(Guid personaKey, int score)`, `ScoreCustomerJourneyStep(long customerJourneyStepId, int score)`, and `ScoreCustomerJourneyStep(Guid stepKey, int score)` should only be used within the context of a regular HttpContext request, as they automatically resolve the current visitor.
88117
{% endhint %}
118+
119+
## Available Method Overloads
120+
121+
### IPersonaService
122+
123+
| Method | Parameters | Use Case |
124+
|--------|------------|----------|
125+
| `ScorePersona` | `(long personaId, int score)` | Within HttpContext, using numeric ID |
126+
| `ScorePersona` | `(Guid personaKey, int score)` | Within HttpContext, using GUID key (preferred) |
127+
| `ScorePersona` | `(Guid visitorExternalId, long personaId, int score, PersonalizationScoreType scoreType)` | Outside HttpContext, using numeric ID |
128+
| `ScorePersona` | `(Guid visitorExternalId, Guid personaKey, int score, PersonalizationScoreType scoreType)` | Outside HttpContext, using GUID key (preferred) |
129+
130+
### ICustomerJourneyService
131+
132+
| Method | Parameters | Use Case |
133+
|--------|------------|----------|
134+
| `ScoreCustomerJourneyStep` | `(long customerJourneyStepId, int score)` | Within HttpContext, using numeric ID |
135+
| `ScoreCustomerJourneyStep` | `(Guid stepKey, int score)` | Within HttpContext, using GUID key (preferred) |
136+
| `ScoreCustomerJourneyStep` | `(Guid visitorExternalId, long customerJourneyStepId, int score, PersonalizationScoreType scoreType)` | Outside HttpContext, using numeric ID |
137+
| `ScoreCustomerJourneyStep` | `(Guid visitorExternalId, Guid stepKey, int score, PersonalizationScoreType scoreType)` | Outside HttpContext, using GUID key (preferred) |

17/umbraco-engage/developers/settings/custom-goals-scoring.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ Creating the goal is similar to creating a page view or page event goal. The **g
2020

2121
## Trigger goal in C\#
2222

23-
To trigger the goal, execute C# code during the visitor's pageview. Inject `Umbraco.Engage.Infrastructure.Analytics.Goals.IGoalService`, which has a `TriggerGoal(long goalId, int value)` method. An implementation looks like:
23+
To trigger the goal, execute C# code during the visitor's pageview. Inject `Umbraco.Engage.Infrastructure.Analytics.Goals.IGoalService`, which provides multiple overloads to trigger goals:
24+
25+
- `TriggerGoal(long goalId, int value)` - Using numeric ID
26+
- `TriggerGoal(Guid goalKey, int value)` - Using GUID key (preferred)
27+
28+
An implementation looks like:
2429

2530
```cs
2631
using Umbraco.Engage.Infrastructure.Analytics.Goals;
@@ -31,11 +36,17 @@ public class YourService
3136

3237
public YourService(IGoalService goalService) => _goalService = goalService;
3338

34-
public void TriggerGoal()
39+
public void TriggerGoalById()
3540
{
36-
// Use the goalId from the code snippet above
41+
// Using numeric ID (legacy approach)
3742
_goalService.TriggerGoal(goalId: 37, value: 42);
3843
}
44+
45+
public void TriggerGoalByKey()
46+
{
47+
// Using GUID key (preferred approach)
48+
_goalService.TriggerGoal(goalKey: new Guid("a1b2c3d4-e5f6-7890-abcd-ef1234567890"), value: 42);
49+
}
3950
}
4051
```
4152

@@ -48,7 +59,20 @@ To trigger a goal outside of an HTTP request or a valid pageview, use the overlo
4859
Retrieve the pageview GUID in the original request using `Umbraco.Engage.Infrastructure.Analytics.Common.IPageviewGuidManager.GetPageviewGuid()`. You will need to store this pageview GUID for later use when invoking:
4960

5061
```cs
62+
// Using numeric goal ID
5163
_goalService.TriggerGoal(pageviewGuid, goalId, value);
64+
65+
// Using GUID goal key (preferred)
66+
_goalService.TriggerGoal(pageviewGuid, goalKey, value);
5267
```
5368

5469
This custom goal can now be used like other goals and will show up in any statistics related to goals.
70+
71+
## Available Method Overloads
72+
73+
| Method | Parameters | Use Case |
74+
|--------|------------|----------|
75+
| `TriggerGoal` | `(long goalId, int value = 0)` | Within HttpContext/pageview, using numeric ID |
76+
| `TriggerGoal` | `(Guid goalKey, int value = 0)` | Within HttpContext/pageview, using GUID key (preferred) |
77+
| `TriggerGoal` | `(Guid pageviewGuid, long goalId, int value = 0)` | Outside HttpContext, using numeric ID |
78+
| `TriggerGoal` | `(Guid pageviewGuid, Guid goalKey, int value = 0)` | Outside HttpContext, using GUID key (preferred) |

17/umbraco-engage/getting-started/for-developers/infrastructure-sizing.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ Due to the wide variety of cloud providers, we recommend using the appropriate s
2424

2525
### **Microsoft Azure**
2626

27-
For Azure SQL, use at least a S3 instance with 100 Data Transport Utility (DTU).
27+
For Azure SQL, use at least a **S3 tier (100 DTUs)** or higher.
2828

29-
Umbraco Engage depends on features that aren’t available in the lower tiers and will fail to boot if they are used.
29+
{% hint style="warning" %}
30+
Umbraco Engage requires **columnstore index support** for optimal performance. Azure SQL tiers lower than S3 (such as S0, S1, S2) do not support **creating** columnstore indexes. The initial installation will fail on these lower tiers.
31+
32+
**Workaround:** You can temporarily scale up to S3 for the initial installation, then scale back down. Lower tiers can still **query** columnstore indexes once created. However, this configuration is not recommended for production due to potential performance issues. See [Troubleshooting Installations](troubleshooting-installations.md) for details.
33+
{% endhint %}
3034

3135
## Non-cloud
3236

17/umbraco-engage/getting-started/for-developers/system-requirements.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,41 @@ Umbraco Engage has the following requirements:
88

99
* Umbraco version 17
1010
* .NET 10.0
11-
* SQL Server 2014+, LocalDB, or Azure SQL.
11+
* SQL Server 2014+, LocalDB, or Azure SQL
1212
* **SQL CE & SQLite are not supported.**
1313

1414
{% hint style="info" %}
1515
It is recommended to upgrade your Umbraco installation to the latest version of Umbraco 17.
1616
{% endhint %}
1717

18+
## Database Requirements
19+
20+
Umbraco Engage uses **columnstore indexes** for optimal query performance on analytics data. This has implications for your database choice:
21+
22+
### SQL Server (On-Premises / Self-Hosted)
23+
24+
* **SQL Server 2014 or higher** is required
25+
* Columnstore index support varies by edition - Enterprise Edition is recommended for older SQL Server versions
26+
27+
### Azure SQL
28+
29+
* **S3 tier (100 DTUs) or higher** is required to **create** columnstore indexes during installation
30+
* Lower tiers (S0, S1, S2) can **query** existing columnstore indexes but cannot create them
31+
* See [Infrastructure Sizing](infrastructure-sizing.md) for detailed Azure SQL recommendations
32+
33+
{% hint style="warning" %}
34+
If you attempt to install Umbraco Engage on an Azure SQL tier lower than S3, the initial migration will fail. See [Troubleshooting Installations](troubleshooting-installations.md) for workarounds.
35+
{% endhint %}
36+
37+
### LocalDB
38+
39+
LocalDB supports columnstore indexes and can be used for local development.
40+
1841
See the [Troubleshooting](../../installation/troubleshooting-installs.md) section if you need to upgrade from SQL CE to SQL Server.
1942

20-
Umbraco Engage is compatible with Umbraco Cloud (Standard, Professional and Enterprise plan). 
43+
## Umbraco Cloud Compatibility
44+
45+
Umbraco Engage is compatible with Umbraco Cloud (Standard, Professional and Enterprise plan).
2146

2247
{% hint style="info" %}
2348
If you want to run an Umbraco Cloud site locally, point the connection string to a (local) SQL Server database. SQLite is not supported.

17/umbraco-engage/getting-started/for-developers/troubleshooting-installations.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ After installing Umbraco Engage and booting for the first time, an SQL exception
1515
The most common reasons for this are:
1616

1717
* Database connectivity issues.
18-
* Incompatible SQL Server version.
19-
* No columnstore index support on Azure SQL lower than S3.
18+
* Incompatible SQL Server version or edition (columnstore index support required).
19+
* No columnstore index support on Azure SQL tiers lower than S3 (S0, S1, S2).
2020

2121
### Exception
2222

@@ -58,3 +58,9 @@ Azure SQL lower than S3 doesn't support creating columnstore indexes. To work ar
5858
3. Scale back to your initial Azure SQL tier.
5959

6060
The columnstore indexes are created and can be used in a lower tier.
61+
62+
#### When running on an incompatible SQL Server version or edition
63+
64+
SQL Server 2014 or higher is required. Columnstore index support varies by SQL Server version and edition. If you encounter issues, consider upgrading to a newer SQL Server version or using Enterprise Edition.
65+
66+
See [System Requirements](system-requirements.md) for the full list of supported database configurations.

0 commit comments

Comments
 (0)