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 43 posts 97 karma points
    Sep 12, 2019 @ 09:08
    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 1593 posts 7151 karma points MVP 6x c-trib
    Sep 12, 2019 @ 09:25
    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 43 posts 97 karma points
    Sep 12, 2019 @ 10:49
    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 1593 posts 7151 karma points MVP 6x c-trib
    Sep 12, 2019 @ 12:39
    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 43 posts 97 karma points
    Sep 13, 2019 @ 10:11
    Paul Aikman
    0

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

  • Matt 76 posts 280 karma points
    Jan 16, 2020 @ 05:52
    Matt
    0

    Hey Nik,

    I'm using a similar approach to this for a multi-select list of categories on a blog entry.

    The issue I've run into is that if there is a category of "something" and another category of "something else", when you search for a category name of "something" via Searcher.CreateQuery, you'll get blog entries that have either of those 2 categories. Have you come across that issue and solved it?

    Regards, Matt

Please Sign in or register to post replies

Write your reply to:

Draft