Copied to clipboard

Flag this post as spam?

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


  • Bjarne Fyrstenborg 1286 posts 4060 karma points MVP 9x c-trib
    Apr 20, 2021 @ 18:07
    Bjarne Fyrstenborg
    0

    Examine search nodes with data from children

    Hi..

    I have a use-case where I have some BrandPage nodes, which has a training archive as child node. In this archive some training nodes will be created via a form.

    A specific member type has then access to from frontend the mark these training nodes as completed. Basically it just set the value of a property to 1 using boolean datatype.

    I can search the BrandPage nodes using Examine using the following:

    public class BrandSurfaceController : SurfaceController
    {
        private readonly IExamineManager _examineManager;
        private readonly IUmbracoContextAccessor _umbracoContextAccessor;
    
        public BrandSurfaceController(IExamineManager examineManager, IUmbracoContextAccessor umbracoContextAccessor)
        {
            _examineManager = examineManager;
            _umbracoContextAccessor = umbracoContextAccessor;
        }
    
        [ChildActionOnly]
        public ActionResult BrandList(int p = 1, int ps = 50)
        {
            return PartialView("PagedBrandList", GetPagedBrands(p, ps));
        }
    
        private PagedResult<BrandPage> GetPagedBrands(int page, int pageSize)
        {
            if (_examineManager.TryGetIndex(Constants.UmbracoIndexes.ExternalIndexName, out var index))
            {
                var searcher = index.GetSearcher();
                var query = searcher.CreateQuery()
                    .GroupedOr(new[] { "__NodeTypeAlias" }, new[] {
                        BrandPage.ModelTypeAlias
                    });
    
                var results = query.OrderBy(new SortableField("name", SortType.String)).Execute(pageSize * page);
                var totalResults = results.TotalItemCount;
                var pagedResults = results.Skip(pageSize * (page - 1));
    
                var items = pagedResults.ToPublishedSearchResults(_umbracoContextAccessor.UmbracoContext.Content)
                    .Select(x => x.Content)
                    .OfType<BrandPage>()
                    .OrderBy(x => x.SortOrder);
    
                return new PagedResult<BrandPage>(totalResults, page, pageSize)
                {
                    Items = items
                };
            }
    
            return new PagedResult<BrandPage>(0, page, pageSize);
        }
    }
    

    At some point e.g. a BrandPage could then have 4/5 trainings marked as completed, other could have 5/5 or 10/10.

    My question is then how to filter brand which does not have completed all trainings. e.g 2/5 or 8/10.

    I can imagine a few approaches, but maybe there is a better way to handle this:

    1. A second Examine search query filtering training nodes and joining the results with the brand page results.

    2. Using TransformingIndexValues event to index the number of completed training nodes in a new field. However when a new training node is created or marked as completed it would require to re-index the result of the training node.

    /Bjarne

  • Nik 1625 posts 7295 karma points MVP 8x c-trib
    Apr 20, 2021 @ 21:32
    Nik
    0

    Hey Bjarne,

    If it was me, I'd go with your second option because Examine doesn't lend itself to what I would call "conditional" searching like that. So when a new training node is created (saved/published) you could tell examine to explicitly re-index it's parent.

    A third option is to store the "Completed" status in a custom DB table and then search that instead. The table could be as basic as:

    Brand, Training, Completed
    

    Then you could search for any distinct Brand where Completed = false.

    You could cache the results as well to reduce DB hits.

    Just an alternative :-)

    Nik

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies