Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Hugo Migneron 32 posts 105 karma points
    Oct 27, 2013 @ 23:24
    Hugo Migneron
    0

    uQuery vs Examine vs IPublishedContent for Querying

    Hi,

    I am trying to query my entire site tree for nodes of a certain document type for which a property matches a certain value. With uQuery I had :

    uQuery.GetNodesByType("docTypeAlias")
    .Where(elm => elm.GetProperty<int>("propAlias") == id);

    which worked perfectly fine. I am using MVC though so I need IPublishedContent while uQuery returns Nodes.

    So I could do : 

    UmbracoHelper helper = new UmbracoHelper(UmbracoContext.Current);
    uQuery.GetNodesByType("docTypeAlias")
         .Where(elm => elm.GetProperty<int>("propAlias") == id)
         .Select(elm => helper.TypedContent(elm.Id));

    and that will give me IPublishedContent which is what I need. I read a few posts on the forum saying that uQuery was no longer the way to go I haven't found exactly how to do it simply with the methods described in the MVC docs : http://our.umbraco.org/documentation/reference/Templating/Mvc/querying

    TypedContentAtRoot returns an IEnumerable which makes it harder to query all the nodes on my site using that method (though not impossible at all. Only that my code is nowhere near as clear as the uQuery version).

    I also tried the Examine route and ended up with : 

    var criteria = ExamineManager.Instance.SearchProviderCollection["MySearcher"].CreateSearchCriteria("content");
    var filter = criteria.NodeTypeAlias("docTypeAlias")
                 .And()
                 .Field("propAlias", id.ToString());
    UmbracoHelper helper = new UmbracoHelper(UmbracoContext.Current);
    var results = helper.TypedSearch(filter.Compile());

    Once again, this works fine. I like it a bit less because I have to convert my query (id) to a string but it also works. I only have a limited amount of data I can test on so I don't know if I should consider speed in my how I will do it. And if I do, which way should I go.

    I will have ~5000 nodes that I will be querying on.

    What's the correct way to go for that?

    Thanks a lot!

  • Shannon Deminick 1525 posts 5271 karma points MVP 2x
    Oct 28, 2013 @ 02:23
    Shannon Deminick
    100

    Hi Hugo,

    uQuery and INode are essentially obsolete, you should be using IPublishedContent everywhere. There might be some extension methods that need to be created on top of IPublishedContent for making things this like this a bit simpler.

    The query you are trying to execute is a fairly intensive one with 5000+ nodes. Is there a reason you need to query your whole site for nodes of a specific type?

    Using Examine will have the fastest execution time for something like this.

    Here's an extension method you could create (we'll add this to the core) for acheiving this with IPublishedContent:

    public static IEnumerable<IPublishedContent> DescendantsOrSelf(this IEnumerable<IPublishedContent> parentNodes, string docTypeAlias)
    {
        return parentNodes.SelectMany(x => x.DescendantsOrSelf(docTypeAlias));
    } 
    

    Then in your mvc view you could do:

    @Umbraco.TypedContentAtRoot().DescendantsOrSelf("docTypeAlias");
    

    Also note that in nearly all base classes that are shipped with Umbraco including controllers, views, etc... we always expose an Umbraco helper already, you generally don't have to create one yourself. In UmbracoTemplatePage and UmbracoViewPage

  • Shannon Deminick 1525 posts 5271 karma points MVP 2x
    Oct 28, 2013 @ 02:29
    Shannon Deminick
    0

    Oh and there's another method which you can use too that's available in 6.1+

    @Umbraco.TypedContentAtXPath("//[@nodeTypeAlias='blah'])
    

    My XPath is ultra rusty so not sure if that is the exact xpath syntax, but that would work for you too.

  • Shannon Deminick 1525 posts 5271 karma points MVP 2x
    Oct 28, 2013 @ 02:36
    Shannon Deminick
    0

    I've added that method to 6.2 in revision: 49d5791825bfb4293e9daafdb378cc463e49aa5f

  • Hugo Migneron 32 posts 105 karma points
    Oct 28, 2013 @ 05:55
    Hugo Migneron
    0

    Thanks a lot Shannon,

    I am building an archive for a publication that has a fairly big archive (5000 or so articles). Each article is a node in my Umbraco site. I want to be able to navigate the archives using different methods. For example, using a "Category" (which is a field in my "Article" Document Type). This is not the only criteria but one of the, hence the query I am trying to execute. If I shouldn't be doing this for what I am trying to achieve please let me know. If it makes a difference, the website has < 50 nodes that are not of the "Article" document type. All the rest is article. I am building an examine search index only for that document type.

    Otherwise, there is one thing I don't understand in your first post. You say that examine will give me the fastest result and then then post the extension method with 

    parentNodes.SelectMany(x => x.DescendantsOrSelf(docTypeAlias));

    Will that use examine in the background? If not, what does it use?

    Thanks again!

    -Hugo

  • Shannon Deminick 1525 posts 5271 karma points MVP 2x
    Oct 28, 2013 @ 05:59
    Shannon Deminick
    0

    Sorry, didn't mean to be confusing there :)

    For that number of records I'd suggest sticking with the Examine solution you came up with since that will be much quicker in terms of processing.

    Otherwise, if you don't want to use Examine, then you can use that extension method or the XPath method. That extension method is just a simple Linq statement to IPublishedContent. So if you use it like this:

    @Umbraco.TypedContentAtRoot().DescendantsOrSelf("docTypeAlias");
    

    It will find all nodes in your site with the doc type alias 'docTypeAlias'.

    Make more sense ?

  • Hugo Migneron 32 posts 105 karma points
    Oct 28, 2013 @ 06:02
    Hugo Migneron
    0

    Sure does, thank you.

    Just out of curiosity, the LINQ queries to IPublishedContent use the content cached by umbraco if they don't use the examine index? Do they hit the DB for a high number of nodes like that?

  • Shannon Deminick 1525 posts 5271 karma points MVP 2x
    Oct 28, 2013 @ 06:06
    Shannon Deminick
    0

    IPublishedContent does not hit the database at all for content. These entities are still coming from the XML file (not examine) and soon we'll be able to change that out to any different caching medium (provider based - could be Examine/Lucene as an option).

    That said, the IPublishedContent returned for Media does come from Examine since there's no XML file for media. If it's not found their it will go to the db and be cached.

  • Hugo Migneron 32 posts 105 karma points
    Oct 28, 2013 @ 06:09
    Hugo Migneron
    0

    Thank you so much for your help!

Please Sign in or register to post replies

Write your reply to:

Draft