Hello I have just read a post by core team member/developer Shannon on custom MVC routing which is great.
In his example code he uses Examine to find a node with a specific nodetype alias and node name, however I was curious to know why Shannon, didn't use the new ContentService API to do a LINQ expression to find the same node he was after.
So the question I pose is this: When should I be using Examine and when should I be using ContentService API?
If I should be examine alot, then couldn't the ContentService API just be a friendly API wrapper or layer on top of Examine instead?
What do you think, would love to hear your thoughts on this.
I think it's personal preference. Personally I'd never use Examine for this kind of task, because it's not reliable enough; it's not certain the indexes are complete and up-to-date.
An example of where I should have used lucene is the "latest comments dashboard" control in uBlogsy. The dashboard is slow as it basically gets all descendents of the blog landing node. On 1000 nodes that's assumingly 1000+ hits to the db - correct me of i'm wrong.
When dealing with a lot of nodes that need traversing/searching (eg. 2000+) then lucene is the only choice. But there are caveats. The indexes might not be up to date, so what ever results you get back, you need to check of the node actually exits. I would then use the Content Service to get the raw data from the db
I find that it pays to get the actual IContent ot IPublishedContent after you get a search result. That way you can actually get the up to date data. I have an extention method in uBlogsy to get an IPublishedContent from a SearchResult. Should be one for IContent too.
We could do with Morten or Shannon to chip on this thread with the official Core response on the differences between ContentService (IContent, IPublishedContent, NodeFactory & Examine etc...)
I believe - as Anthony suggests - the reason for using Examine rather than the ContentService API would be performance. The API seems more intended for writes and back-office type CRUD operations when you want the latest information. Rather than front-end reads - for which you would want the caching/speed that NodeFactory or Examine provides.
I replied on my blog post but will reply here too...
@Warren: I think you skipped the part in the blog post that explains the different ways that you could look up the content.
You should definitely not use the ContentService to lookup content because that is at the repository/database level, not the cache level. You should only use the ContentService when you need to manipulate content in the database.
The ways to lookup content from cache are: Examine, a Linq query based on the result of Umbraco.TypedContentAtRoot() (but I wouldn’t recommend that since it will be much slower), OR
In v6.1 the UmbracoHelper exposes a couple of other methods that you could use to perform if you want to use XPath instead:
@Anthony, NodeFactory is completely legacy, IPublishedContent does not wrap Node or NodeFactory it is similar but stands apart from that API, it is recomended to drop NodeFactory entirely as it is obsolete.
@kipusoep, IPublishedContent IS readonly, you cannot write to it and you can lookup IPublishedContent from the methods found on the UmbracoHelper
So, to wrap it up, the reason I used Examine in my blog post was because in 6.0 we hadn't implemented a sufficient published content lookup API and only exposed 2 ways to do that: TypedSearch or TypedContentAtRoot. But in 6.1 we have TypedContentSingleAtXPath & TypedContentAtXPath
Of course if you wanted to route by Id, you can just use the method TypedContent which exists from version 4.10
@kipusoep if you have problems with your indexes please log bugs, Examine should always be up to date. This however depends on if you are manipulating the database directly or doing something else which causes events to not execute to keep Examine up to date. It has become far more stable in recent releases but this is mostly due to the core stability being improved to ensure that events are triggered.
I didn't know the (I)PublishedContent(Service) was ready for usage in C#. I've asked about this before on Twitter and didn't really know what to do with it:
So in v6.1(+), when using plain C# with UserControls and MasterPage code-behind, is using this IPublishedContent the way to go in favor of the NodeFactory? :-)
It's not, as I mentioned you access these methods via the UmbracoHelper. There's been methods on the UmbracoHelper for retreiving content since 4.10 but they didn't include the new ones that allow you to use XPath, these were introduced in 6.1
Yes, there are numerous base classes for both webforms and mvc that you should use that expose all the proper Umbraco objects like UmbracoHelper, UmbracoContext, ApplicationContext, etc... You should use these base classes and the UmbracoHelper to query for data.
For UserControls, there's this base class: Umbraco.Web.UI.Controls.UmbracoUserControl found in the umbraco.dll assembly, you should inherit from that for your user controls and it will expose all the new Umbraco bits that you want.
This threat was very helpful. I've been working on a user control for the Dashboard and I was struggling with querying the CMS and dealing with the result set from Content Service in a Umbraco 7 MCV environment. Using Examine to get my results and structure my query seems to do the trick and is a be eaiser to deal with.
When to use which method and library when you are working in different scenarios is very confusing when someone (like me) is transitioning from Webforms to MVC. Would be great to have some sort of guide for this.
There's a very important thing to note when working with Umbraco: Never use the back office services APIs in your front-end, especially the content APIs since this goes directly to the database. Examine is an alternate way of working with data on the front-end but the normal and documented way is working with the IPublishedContent which is the model that is given to you by default in your views
Umbraco 6: ContentService API or Examine?
Hello I have just read a post by core team member/developer Shannon on custom MVC routing which is great.
In his example code he uses Examine to find a node with a specific nodetype alias and node name, however I was curious to know why Shannon, didn't use the new ContentService API to do a LINQ expression to find the same node he was after.
So the question I pose is this: When should I be using Examine and when should I be using ContentService API?
If I should be examine alot, then couldn't the ContentService API just be a friendly API wrapper or layer on top of Examine instead?
What do you think, would love to hear your thoughts on this.
Thanks,
Warren :)
The forum post in question that Shannon wrote is this:
http://shazwazza.com/post/Custom-MVC-routing-in-Umbraco
I think it's personal preference. Personally I'd never use Examine for this kind of task, because it's not reliable enough; it's not certain the indexes are complete and up-to-date.
An example of where I should have used lucene is the "latest comments dashboard" control in uBlogsy. The dashboard is slow as it basically gets all descendents of the blog landing node. On 1000 nodes that's assumingly 1000+ hits to the db - correct me of i'm wrong.
When dealing with a lot of nodes that need traversing/searching (eg. 2000+) then lucene is the only choice. But there are caveats. The indexes might not be up to date, so what ever results you get back, you need to check of the node actually exits. I would then use the Content Service to get the raw data from the db
I find that it pays to get the actual IContent ot IPublishedContent after you get a search result. That way you can actually get the up to date data. I have an extention method in uBlogsy to get an IPublishedContent from a SearchResult. Should be one for IContent too.
@Anthony
"On 1000 nodes that's assumingly 1000+ hits to the db - correct me of i'm wrong."
I hereby correct you ;-) The NodeFactory doesn't hit the DB at all.
@stefan kip but does the ContentService API do as many DB calls?
IPublishedContent is a wrapper around NodeFactory which hits the xml cache.
But we're talking about ContentService which returns an IContent, not IPublishedContent.
ContentService is a replacement for the Document API, which hit the db really inefficiently. ContentService is just more efficient at db access?
At least that's my understanding. Again correct me of I'm wrong about ContentService.
We could do with Morten or Shannon to chip on this thread with the official Core response on the differences between ContentService (IContent, IPublishedContent, NodeFactory & Examine etc...)
Ah yes, sorry, was already assuming using the NodeFactory instead of the ContentService :-)
I wish there was a PublishedReadOnlyContentService, so the NodeFactory could retire too...
I believe - as Anthony suggests - the reason for using Examine rather than the ContentService API would be performance. The API seems more intended for writes and back-office type CRUD operations when you want the latest information. Rather than front-end reads - for which you would want the caching/speed that NodeFactory or Examine provides.
Andy
I replied on my blog post but will reply here too...
@Warren: I think you skipped the part in the blog post that explains the different ways that you could look up the content.
You should definitely not use the ContentService to lookup content because that is at the repository/database level, not the cache level. You should only use the ContentService when you need to manipulate content in the database.
The ways to lookup content from cache are: Examine, a Linq query based on the result of Umbraco.TypedContentAtRoot() (but I wouldn’t recommend that since it will be much slower), OR
In v6.1 the UmbracoHelper exposes a couple of other methods that you could use to perform if you want to use XPath instead:
TypedContentSingleAtXPath(string xpath, params XPathVariable[] vars)
TypedContentAtXPath(string xpath, params XPathVariable[] vars)
TypedContentAtXPath(XPathExpression xpath, params XPathVariable[] vars)
@Anthony, NodeFactory is completely legacy, IPublishedContent does not wrap Node or NodeFactory it is similar but stands apart from that API, it is recomended to drop NodeFactory entirely as it is obsolete.
@kipusoep, IPublishedContent IS readonly, you cannot write to it and you can lookup IPublishedContent from the methods found on the UmbracoHelper
So, to wrap it up, the reason I used Examine in my blog post was because in 6.0 we hadn't implemented a sufficient published content lookup API and only exposed 2 ways to do that: TypedSearch or TypedContentAtRoot. But in 6.1 we have TypedContentSingleAtXPath & TypedContentAtXPath
Of course if you wanted to route by Id, you can just use the method TypedContent which exists from version 4.10
@kipusoep if you have problems with your indexes please log bugs, Examine should always be up to date. This however depends on if you are manipulating the database directly or doing something else which causes events to not execute to keep Examine up to date. It has become far more stable in recent releases but this is mostly due to the core stability being improved to ensure that events are triggered.
I didn't know the (I)PublishedContent(Service) was ready for usage in C#. I've asked about this before on Twitter and didn't really know what to do with it:
https://twitter.com/kipusoep/status/310035598075387904
So in v6.1(+), when using plain C# with UserControls and MasterPage code-behind, is using this IPublishedContent the way to go in favor of the NodeFactory? :-)
It's not, as I mentioned you access these methods via the UmbracoHelper. There's been methods on the UmbracoHelper for retreiving content since 4.10 but they didn't include the new ones that allow you to use XPath, these were introduced in 6.1
Yes, there are numerous base classes for both webforms and mvc that you should use that expose all the proper Umbraco objects like UmbracoHelper, UmbracoContext, ApplicationContext, etc... You should use these base classes and the UmbracoHelper to query for data.
Yes... i still need to document everything :)
Great, I'm a bit tired of working with the NodeFactory and Node objects, so looking forward to work with those new services and models :)
Awesome :)
For UserControls, there's this base class: Umbraco.Web.UI.Controls.UmbracoUserControl found in the umbraco.dll assembly, you should inherit from that for your user controls and it will expose all the new Umbraco bits that you want.
This threat was very helpful. I've been working on a user control for the Dashboard and I was struggling with querying the CMS and dealing with the result set from Content Service in a Umbraco 7 MCV environment. Using Examine to get my results and structure my query seems to do the trick and is a be eaiser to deal with.
When to use which method and library when you are working in different scenarios is very confusing when someone (like me) is transitioning from Webforms to MVC. Would be great to have some sort of guide for this.
Hi,
There's a very important thing to note when working with Umbraco: Never use the back office services APIs in your front-end, especially the content APIs since this goes directly to the database. Examine is an alternate way of working with data on the front-end but the normal and documented way is working with the IPublishedContent which is the model that is given to you by default in your views
http://our.umbraco.org/documentation/Reference/Templating/Mvc/views
http://our.umbraco.org/documentation/reference/templating/mvc/querying
is working on a reply...