Copied to clipboard

Flag this post as spam?

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


  • Paul Aikman 42 posts 96 karma points
    1 week ago
    Paul Aikman
    0

    Umbraco 8: Searching Multi Node Tree Picker Content

    Hi,

    I'm looking to filter blog posts by category in a project I'm building in Umbraco 8, but I'm not sure how to have examine search the categories (selected in the back office via a multi-node tree picker) when filtering posts?

    Right now I have

    • Blog Posts
      • Blog Post
        • Category 1, Category 2 (MNTP "categories" field)
    • Categories
      • Category 1 (has a "name" field to be filtered)
      • Category 2 (has a "name" field to be filtered)

    A record looks like this:

    enter image description here

    So I guess I need some way to search inside the "categories" field to find the category node name(s) I'm looking for?

    I was thinking as a fallback I could pull the categories back and find the ones with the ID's I was interested in so I could string match on the categories field, but this seems a bit... hacky?!

    Cheers,

    Paul

  • Nik 1110 posts 4633 karma points MVP 2x c-trib
    1 week ago
    Nik
    0

    Hi Paul,

    Okay, so a bit off topic but this blog post shows how you can manipulate the data going into the Examine Index (bit of self plugging as I wrote it the other day) https://www.justnik.me/blog/indexing-sort-able-dates-in-umbraco-version-8

    But, this should give you a base idea of manipulating the index to put friendly names into the index.

    To help with this I use a function a bit like this:

    private void HandleMultiNodeTreePicker(IndexingItemEventArgs e, IPublishedContent content, string propertyAlias)
    {
        try
        {
            var processed = new List<object>();
            if(content.HasProperty(propertyAlias) && content.HasValue(property))
            {
                IPublishedContent treeNode;
                using(var umbracoContext = umbracoContextFactory. EnsureUmbracoContext())
                {
                    foreach(var entry in e.ValueSet.Values[propertyAlias].Cast<string>())
                    {
                        foreach(var udi in entry.Split(',').Select(s=>GuidUdi.Parse(s)))
                        {
                            treeNode = umbracoContext.UmbracoContext.Content.GetById(udi);
                            processed.Add(treeNode.Name);
                        }
                    }
                }
                e.ValueSet.Values.Add(propertyAlias + "Cleaned", processed);
            }
        }
        catch(exception e)
        {
            //do some error logging here
        }
    }
    

    This adds a field to the index with the alias of your multi-node tree picker property and "Cleaned" appended to the end.

    Then when you are searching you can do a text search against this field for your category :-)

    Hope that helps

    Nik

  • Paul Aikman 42 posts 96 karma points
    1 week ago
    Paul Aikman
    1

    Cheers Nik! Yeah that gave me enough to put something together.

    The indexer I think I'll eventually put some more work into to create a separate index, but updating the external index works for now.

    Here's roughly what I came up with (was nice that I could use the strongly typed model in U8):

        public void Initialize()
        {
            if (examineManager.TryGetIndex("ExternalIndex", out IIndex externalIndex))
            {
                externalIndex.FieldDefinitionCollection.AddOrUpdate(new FieldDefinition("postDate", FieldDefinitionTypes.DateTime));
    
                ((BaseIndexProvider)externalIndex).TransformingIndexValues += IndexerComponent_TransformingIndexValues;
            }
        }
    
        private void IndexerComponent_TransformingIndexValues(object sender, IndexingItemEventArgs e)
        {
            if (int.TryParse(e.ValueSet.Id, out var nodeId))
                switch (e.ValueSet.ItemType)
                {
                    case "EqtrBlogPostPage":
                        using (var umbracoContext = umbracoContextFactory.EnsureUmbracoContext())
                        {
                            var contentNode = umbracoContext.UmbracoContext.Content.GetById(nodeId);
                            if (contentNode != null)
                            {
                                var blogNode = contentNode as EqtrBlogPostPage;
    
                                List<string> categoryNames = new List<string>();
    
                                var articleDate = blogNode.PostDate;
                                e.ValueSet.Set("postDate", articleDate.Date.ToString("dd/MM/yyyy"));
    
                                foreach (var category in blogNode.Categories)
                                {
                                    categoryNames.Add(category.Name);
                                }
    
                                e.ValueSet.Set("categoryNames", string.Join(",", categoryNames.ToArray()));
                            }
                        }
                        break;
                }
        }
    
  • Nik 1110 posts 4633 karma points MVP 2x c-trib
    1 week ago
    Nik
    0

    Looks good, bit of advice though, the way you are storing your date in the index won't be sortable if you did want examine to sort on the date. Just so you are aware.

    The post I linked to talks about this so if this is something you need to consider it's worth a read :-)

    Thanks

    Nik

  • Paul Aikman 42 posts 96 karma points
    1 week ago
    Paul Aikman
    0

    Ahh cool, was having some range query issuses with DateTime as well - changing to ticks sorted it out.

Please Sign in or register to post replies

Write your reply to:

Draft