GetContent - Projection with image and URL

Vote:
 

I've been playing around with EpiServer search, and have successfully managed to use it to filter some pages and pull out the relevant content items using GetContentResult(). I've also managed to use GetResult() to project some simple properties into a custom object.

My question is whether it is possible to have any sort of hybrid between the two? I want to show a list of the search items on a page - and it's fine for some title and description text. But how would I 1) get the URL to the page, without using GetContentResult(), and 2) is it possible to get an image in a projection too?

Something like this?

var query = _findClient.Search<MyPage>()
                  .Filter(filter)
                  .FilterForVisitor()
                  .OrderByDescending(hap => hap.DatePublished)
                  .Take(20)
                  .Select(mp => new NewsArticleSummaryModel
                  {
                       PageHeading = mp.PageHeading,
                       DatePublished = mp.DatePublished,
                       TeaserText = mp.TeaserText,
                       TeaserImage = mp.TeaserImage // ??? possible?
                       Url = // ??? how?
                   });                 

I ask as getting 20 items out using GetContentResult() seems quite a bit slower. I know GetResult doesn't hit the DB, and uses the index instead, but surely it's at least possible to get the URL and image without pulling out the entire page?

I assume I could get the IDs and fetch them individually, but that seems fiddly. Is there another way?

#225506
Edited, Jul 18, 2020 14:54
Vote:
 

Yeah, it is possible with indexing additional fields.

public static class IContentExtensions
{
    public static string Url(this IContent content)
    {
        var urlResolver = ServiceLocator.Current.GetInstance<UrlResolver>();
        return urlResolver.GetUrl(content.ContentLink);
    }
}

[InitializableModule]
[ModuleDependency(typeof(EPiServer.Find.Cms.Module.IndexingModule))]
public class IndexingEventInitialization : IConfigurableModule
{
    public void Initialize(InitializationEngine context)
    {
        SearchClient.Instance.Conventions.ForInstancesOf<MyPage>()
                    .IncludeField(x => x.Url());
    }
}

And when you are getting it back

var query = _findClient.Search<MyPage>()
                  .Filter(filter)
                  .FilterForVisitor()
                  .OrderByDescending(hap => hap.DatePublished)
                  .Take(20)
                  .Select(mp => new NewsArticleSummaryModel
                  {
                       PageHeading = mp.PageHeading,
                       DatePublished = mp.DatePublished,
                       TeaserText = mp.TeaserText,
                       TeaserImage = mp.TeaserImage,
                       Url = mp.Url()
                   }); 

For the image, you do the same :) 

#225526
Jul 19, 2020 11:11
Vote:
 

Agree with what Sebbe said, the beauty of Find is you can add what you need to your index for later uses. Note that this is Find, and to some extend, Find.Commerce, not FindSearchProvider

#225527
Jul 19, 2020 15:25
Vote:
 

Personally I prefer adding readonly properties to my models for the Find indexing of custom fields. I just like knowing where everything is for a class/object rather than in initalization models. I'd usually create an interface for indexable properties and add that to the IContent types so there's a clear separating of content properties and indexing properties. But that's just my personal preference but a good optional choice.

#225550
Jul 20, 2020 9:13
Praful Jangid - Jul 20, 2020 19:26
I also prefer to follow this approach. Infect I am right now using that in my running project ;).
Vote:
 

Thanks so much all - that worked perfectly!

Apologies for the incorrect tag - I have corrected now.

#225556
Jul 20, 2020 18:33
- Aug 03, 2020 12:33
Do you mind marking post as solved?
* 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.