Getting descendants?

Vote:
 

Hi,

i wonder how i would go about getting results from all descendants of a parent node?

In the code i´m modifying, all articles below a parent node is gathered. However, our client has need for sorting the articles by year, so i have added folders below the parent for each year and moved all corresponding articles into these. I would need to get all articles from these sub-folders in the way i got them before.

I´m running version epi 6.1.379.0. The current code, without any of my modifications:

var query = GetSiteSearchBase<PageTypeBase>(q);

query = Filter<T>(query, page, pageSize, sort, area, type, publication, year, parentId);
query = query.StaticallyCacheFor(new TimeSpan(0, 0, 5, 0));
return query.GetPagesResult();

 

I tried just looping and adding new id´s into parentId, but that does not work, or maybe i´m doing it wrong.

 

Any ideas?

 

Thanks! / MarcusB

#79910
Jan 09, 2014 14:09
Vote:
 

FindPagesByCriteria is your friend. Then use EPiServer.Filter to filter for visitor (removed the expired ones and the ones that you do not have access to). Then use LINQ, skip and take to solve paging if needed...
FindPagesByCriteria combined with multiple languages and PageTypeBuilder is not always friends so I would recommend doing it the old fashioned way to avoid some bugs I've seen :)
If you are using it to produce a listing, remember to cache the result to avoid any performance problems...

#79912
Edited, Jan 09, 2014 14:22
Vote:
 

Hi,

Can you provide the code snippet for "Filter<T>(query, page, pageSize, sort, area, type, publication, year, parentId);"?

/Henrik

#79913
Jan 09, 2014 14:26
Vote:
 

Daniel; i will look into it - thanks!

Henrik - certainly, here it is:

 

private ITypeSearch<PageTypeBase> Filter<T>(ITypeSearch<PageTypeBase> query, int page = 1, int pageSize = 20, string sort = null, int area = -1, int type = -1, int publication = -1, int year = 0, int? parentId = null) where T : PageTypeBase
{
if (typeof(T) == typeof(PublicationPageType))
{
query = query.OrderByDescending(x => ((PublicationPageType)x).Published);
}
else
{
switch (sort)
{
case "date":
query = query.OrderByDescending(x => x.StartPublish);
break;
}
}

if (area >= 0)
{
query = query.Filter(x => x.Category.Match(area));
}
if (type >= 0)
{
query = query.Filter(x => x.Category.Match(type));
}
if (publication >= 0)
{
query = query.Filter(x => x.Category.Match(publication));
}
if (year > 0)
{
query = query.Filter(x => x.StartPublish.InRange(new DateTime(year, 1, 1, 0, 0, 1), new DateTime(year, 12, 31, 11, 59, 59)));
}
if (parentId.HasValue)
{
query = query.Filter(x => x.ParentLink.ID.Match(parentId.Value));
}
return query
.Filter(x => x.MatchTypeHierarchy(typeof (T)))
.Skip(pageSize*(page - 1))
.Take(pageSize);
}

 

 

 

Also, both of the code blocks in my posts gets called here:

var pages = FindHelper.Instance.SearchSitePages<ArticlePageType>(string.Empty, Pager.CurrentPageNumber, CurrentPage.PageSize, "date", Facets.ArticleArea, Facets.ArticleType, Facets.Publication, Facets.ArticleYear, CurrentPage.PageLink.ID);

If i could pass in the all id´s for the children as nodes to retrieve results from, i would be home safe, i guess. Tried to circumvent this but have not found a way to merge several results into one, unforttunately.

//Marcus

#79915
Edited, Jan 09, 2014 15:01
Vote:
 

If I understand you correctly what have changed is this. Before you had the following structure:

articles
- article1
- article2
-...

and you could filter all articles on ParentLink.ID == articles

Now you have:

articles
- 2013
 - article1
 - article2
 - ...
-2012
 - article3

but when filtering on ParentLink.ID == articles it fails since the "year"-folders are inbetween.

To solve this you could instead filter on Ancestors:

.Filter(x => x.Ancestors().Match(parentOfParentReference.CreateReferenceWithoutVersion().ToString()))

/Henrik

#79918
Jan 09, 2014 17:17
Vote:
 

Spot on, Henrik. 

I will try this out first thing tomorrow and let the thread know of my progress. Thanks! :)

 

//Marcus

#79919
Edited, Jan 09, 2014 17:21
Vote:
 

Hi again,

 

since i´m running epi ver. 6, i can´t find the Ancestors anywhere. Or is it a method reference? Care to explaing further (i´m a newbie to epi, as you might have guessed).

 

I´ve managed to get all the result by another method, but i still need to use a pager to the result list.

 

//Marcus

#79997
Jan 13, 2014 12:57
Vote:
 

Hi,

The Ancestors() extension was added for the cms 7 integration. However you can easily add it yourself. Create the extension:

public static IEnumerable<string> Ancestors(this PageData page)
{
var ancestorLinks = DataFactory.Instance.GetParents(page.PageLink);
var ancestors = DataFactory.Instance.GetPages(ancestorLinks, LanguageSelector.AutoDetect(true));
return ancestors.Select(x => x.PageLink.ToStringIgnoringWorkId());
}

and then add it to the indexing conventions at startup (Iniitializable module or Global.asax):

SearchClient.Instance.Conventions.ForInstancesOf<PageData>().IncludeField(x => x.Ancestors())

Reindex...

Filter using:

.Filter(x => x.Ancestors().Match(parentOfParentLink.ToStringIgnoringWorkId()))

/Henrik

#80186
Edited, Jan 16, 2014 11:21
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.