Copied to clipboard

Flag this post as spam?

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


  • Kevin C. Halpin 27 posts 108 karma points
    Oct 30, 2018 @ 16:30
    Kevin C. Halpin
    0

    Finding all nodes with document types that inherit from particular document type

    What I have is one common document type which has all the common properties I need (PARENT).. and then I have more document types that inherit from the parent document type and also have additional properties. (CHILDREN ) In the content I only create nodes from these child document types. Is there a query that will return all nodes that have a document type that inherit from the parent document type. Also, I need to do this without using Examine, because that has been nothing but trouble in my experience. I am using Umbraco 7.

  • Michaël Vanbrabandt 863 posts 3348 karma points c-trib
    Oct 30, 2018 @ 16:37
    Michaël Vanbrabandt
    0

    Hi Kevin,

    can you give us a screenshot of the content structure with some more details and the result you want?

    Thanks!

    /Michaël

  • Mark Bowser 273 posts 860 karma points c-trib
    Oct 30, 2018 @ 17:45
    Mark Bowser
    0

    Are you looking for a way to do this on the site? Or are you just looking for an SQL query for auditing purposes?

    I think something like this will get you the data you need:

    var myNodes = new List<IContent>();
    
    var cs = Services.ContentService;
    var cts = Services.ContentTypeService;
    
    var childDocTypes = cts.GetContentTypeChildren(123);
    foreach (var contentType in childDocTypes)
    {
        myNodes.AddRange(cs.GetContentOfContentType(contentType.Id));
    }
    

    Keep in mind that using these services is highly discouraged when you are trying to display results to front end users. These services are meant for programatically creating and updating content, document types, etc. Because these services hit the database directly, they are very slow and expensive. You can use these services to get info about doctypes and unpublished content, but it is one of the most inefficient ways to query Umbraco.

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Oct 31, 2018 @ 09:17
    Dave Woestenborghs
    2

    Hi Kevin,

    If you are using models builder this can be done without using the content service.

    First you need to find all doctypes that implement your base class using this, and exclude the base class it self

    var myDocTypes= PluginManager.Current.ResolveTypes<BasePage>().Where(x => x.Name != nameof(BasePage)).ToList();
    

    Now that you have that list I prefer XPath to find all the items, because we can do it one query.

     var filter = string.Empty;
    
                foreach (var doctype in myDocTypes)
                {
                    var alias = doctype.GetField("ModelTypeAlias");
    
                    if (alias != null)
                    {
                        filter += $"self::{alias.GetValue(null)} or ";
                    }                               
             }
    
     filter =  filter.TrimEnd(" or ");
    
     var xpath = $"id({currentContentId})[@isDoc]/ancestor-or-self::{RootNodeDocTypeAlias}//*[{filter}]";
    

    Of course you need to replace currentContentId with id of your current page and RootNodeDocTypeAlias with the document type alias of your root item.

    After that you can get all the items implementing a certain base type from the cache

    var items = UmbracoContext.Current.ContentCache.GetByXPath(xpath).OfType<BasePage>();
    

    Dave

  • Kevin C. Halpin 27 posts 108 karma points
    Nov 01, 2018 @ 00:41
    Kevin C. Halpin
    0

    Hi guys, thanks for all the answers and sorry for my delay. Actually I am using Umbraco only for BE part, so I am using Umbraco API controllers. So, I guess my only choice is content service??

    Michael here is an example of how my structure looks like. Let's say in the section where I define the document types I have the following:

    ParentDocumentType - InheritedDocumentType1 - InheridetDocumetType2 - InheritedDocumentType3

    And in the content section I only have nodes of the inherited types (InheritedDocumentType1, InheridetDocumetType2 and InheritedDocumentType3).

    So, I was looking for a way to get all the nodes that inherit from the ParentDocumentType, so I don't have to filter by EVERY document type. If you have additional questions and it is still not clear what I want to achieve please ask.. and thanks again.

  • Kevin C. Halpin 27 posts 108 karma points
    Nov 01, 2018 @ 00:43
    Kevin C. Halpin
    0

    I think that I will just define a list with all the document types I need and when I iterate over the nodes I will just check if the document type of the node is in the list. If someone thinks of a better way to do this please do tell :)) Thanks

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Nov 01, 2018 @ 07:16
    Dave Woestenborghs
    0

    Hi Kevin,

    The code I sent should work just fine in a API controller. You only need to tweak your xpath query to start from the root because you don't have a current page id.

    Dave

  • Hendy Racher 863 posts 3849 karma points MVP 2x admin c-trib
    Nov 01, 2018 @ 07:35
    Hendy Racher
    0

    Hi, just a thought but how about adding a unique label property (eg BasedOnDocTypeA) to each of your base docTypes and then doing a regular XPath query looking for all items that have that particular label property (as it will be inherited). To exclude any base docTypes you could check the level is greater than X - or to know if any given content item extends a given base docType then no query is required as it'll have the label property to check.

  • Kevin C. Halpin 27 posts 108 karma points
    Nov 01, 2018 @ 08:52
    Kevin C. Halpin
    0

    Thank you guys for the suggestions. I will try all of these ideas these days and I will get back to you :)

  • Kevin C. Halpin 27 posts 108 karma points
    Nov 11, 2018 @ 18:48
    Kevin C. Halpin
    0

    I found a way to do this by simply checking if the base document type is in the composition aliases .Where(x => x.ContentType.CompositionAliases.ToList().IndexOf("item").

  • Dave Woestenborghs 3504 posts 12133 karma points MVP 8x admin c-trib
    Nov 12, 2018 @ 07:04
    Dave Woestenborghs
    0

    Hi Kevin,

    I think you are using a IContent item here ? Remember you will be hitting the database and bypassing the cache which can cause performance issues.

    Dave

Please Sign in or register to post replies

Write your reply to:

Draft