Is it OK to use Umbraco properties for frequently updated fields?
I am storing a social share count in all my content which updates quite frequently. The counters are updated many times per day (maybe 200,000+).
Is it a problem to use Umbraco properties in this way? Should I store frequently updated data in a dedicated table? What happens (in terms of overhead) when I update a property in Umbraco?
The below runs in a background Task so as not to delay the page load:
var route = new Uri(url);
var nodeByUrl = UmbracoContext.Current.ContentCache.GetByRoute(route.PathAndQuery);
if (null != nodeByUrl && nodeByUrl.HasProperty(ShareCounterField))
{
int sharingCounterValue = totalShares;
if (nodeByUrl.GetPropertyValueAsInt(ShareCounterField) == totalShares)
{
// no change to value, so return;
return;
}
int viewCounterValue = nodeByUrl.GetPropertyValueAsInt(ViewCounterField);
viewCounterValue++;
var node = UmbracoContext.Current.Application.Services.ContentService.GetById(nodeByUrl.Id);
node.SetValue(ShareCounterField, sharingCounterValue);
node.SetValue(ViewCounterField, viewCounterValue);
UmbracoContext.Current.Application.Services.ContentService.Publish(node);
}
For now (new stuff coming) it'll rewrite the entire App_Data\umbraco.config file on each publish.
It'll also update the lucene index with the updated document. And if you're loadbalancing, it'll push a message to (all) the other server(s) and have them do the same.
Depending on the amount of documents in your site, it might be a performance issue.
However, if you don't need to have the freshest count on the web at all times, you can just save the content instead of publishing it. Then it'll just go to the database and you have saved the server quite a lot of work.
It'd be:
It shouldn't be grayed out unless it's been unpublished. It should have a small star or something indicating that there's been changes that hasn't been published yet.
If you go to the Properties page, does it still have an URL?
Below is what I see when I use
ContentService.Save(node); instead of .ContentService.Publish(node);
The content still has a URL and is visible on the site. I think it's because the content in the DB is different from the content in the XML cache. It's causing my users to obsessively "republish all".
Any way to disable this behavior?
Couple of things to consider with this approach. Using the Umbraco Service like this is expensive due to the db traffic it creates. Even though you are updating a single property it will still resave every property in the document.
If you are publishing, it will also rebuild the XML file. If you are using Umbraco Caching, publishing will also invalidate caching every time.
Personally if it is something that is going to be updating as regularly as you mention I would definitely look at a dedicated table for performance reasons.
it will create a new 'version' of the content in the Umbraco database versions table for the particular node (this is to allow editors to roll back to previous versions when managing the content) but in the scenario of incrementing a count property, just chokes your umbraco back office database with thousands of versions of the content, with the only difference between the versions being the count !!
(if you inherit a situation like this, then the UnVersion package is a must install)
Just to chime in on this one: nope, that's not okay for all the above reasons. We've seen this done (heck, I even did it on this very site) and it will lead to performance problems and a huge database. Make sure to refactor the implementation asap to prevent running into these problems.
/me goes to the corner and thinks hard about his lack of good advice ;)
Good rescue guys.
But to address the main use-case here, if you're using Google Analytics, you could look into posting a custom event to it via the JavaScript API. You'd have the social media share count in a more "relevant" data store that way, and you don't even have to go via your server. :)
Is it OK to use Umbraco properties for frequently updated fields?
I am storing a social share count in all my content which updates quite frequently. The counters are updated many times per day (maybe 200,000+).
Is it a problem to use Umbraco properties in this way? Should I store frequently updated data in a dedicated table? What happens (in terms of overhead) when I update a property in Umbraco?
The below runs in a background Task so as not to delay the page load:
For now (new stuff coming) it'll rewrite the entire App_Data\umbraco.config file on each publish. It'll also update the lucene index with the updated document. And if you're loadbalancing, it'll push a message to (all) the other server(s) and have them do the same. Depending on the amount of documents in your site, it might be a performance issue.
However, if you don't need to have the freshest count on the web at all times, you can just save the content instead of publishing it. Then it'll just go to the database and you have saved the server quite a lot of work.
It'd be:
You could for instance do a nightly republish task that updates everything. (Like right clicking the root node and selection publish + children)
Hi Lars,
If I save without publishing the content appears grayed out in Umbraco. This really confuses my users. Can I do anything about that?
It shouldn't be grayed out unless it's been unpublished. It should have a small star or something indicating that there's been changes that hasn't been published yet.
If you go to the Properties page, does it still have an URL?
Below is what I see when I use ContentService.Save(node); instead of .ContentService.Publish(node);
The content still has a URL and is visible on the site. I think it's because the content in the DB is different from the content in the XML cache. It's causing my users to obsessively "republish all". Any way to disable this behavior?
Hey David
Couple of things to consider with this approach. Using the Umbraco Service like this is expensive due to the db traffic it creates. Even though you are updating a single property it will still resave every property in the document.
If you are publishing, it will also rebuild the XML file. If you are using Umbraco Caching, publishing will also invalidate caching every time.
Personally if it is something that is going to be updating as regularly as you mention I would definitely look at a dedicated table for performance reasons.
Yes +1 for dedicated table
Only other bad thing about storing this kind of data (not mentioned above), is that every time you save content in umbraco using
it will create a new 'version' of the content in the Umbraco database versions table for the particular node (this is to allow editors to roll back to previous versions when managing the content) but in the scenario of incrementing a count property, just chokes your umbraco back office database with thousands of versions of the content, with the only difference between the versions being the count !!
(if you inherit a situation like this, then the UnVersion package is a must install)
Yeah, I'd definitely use a dedicated table for this.
Just to chime in on this one: nope, that's not okay for all the above reasons. We've seen this done (heck, I even did it on this very site) and it will lead to performance problems and a huge database. Make sure to refactor the implementation asap to prevent running into these problems.
/me goes to the corner and thinks hard about his lack of good advice ;)
Good rescue guys.
But to address the main use-case here, if you're using Google Analytics, you could look into posting a custom event to it via the JavaScript API. You'd have the social media share count in a more "relevant" data store that way, and you don't even have to go via your server. :)
https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide?hl=en#setting-up-event-tracking
Thanks for the feedback guys!
is working on a reply...