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:
A second Examine search query filtering training nodes and joining the results with the brand page results.
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.
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.
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:
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:
A second Examine search query filtering training nodes and joining the results with the brand page results.
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
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:
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
is working on a reply...