November Happy Hour will be moved to Thursday December 5th.

Getting block data from a UnifiedSearchHit

Vote:
 

I am creating a query which needs to search across pages, blocks and vpp files in my website.

I have decided to use the UnifiedSearchFor approach as this allows me to perform a "free text" type of search against all data in the index.

Out-of-the-box the unified search automatically searches all pages and files but I have had to create an initialisation module to enable my blocks to be available in the unified searches:

SearchClient.Instance.Conventions.UnifiedSearchRegistry.Add<MyBlock>();   

Once I have a UnifiedSearchResults object back from Find, I need to enumerate each result and obtain its origional data to perform further processing record by record.

Using the OriginalObjectGetter property of the UnifiedSearchHit, I am able to successfully obtain a PageData/VersioningFile objects for the page and file UnifiedSearchHit's, but when I try and do this for blocks, the OriginalObjectGetter property is null for the UnifiedSearchHit object.

Is there something extra I need todo in the Find initalisation to enable the OrigionalObjectGetter to work with blocks or is there another way I can use Find to achive what I am trying todo.

Thanks,

Adam

 

 

#72295
Jun 12, 2013 17:13
Vote:
 

Hi,

By default only PageData and UnifiedFile "getters" are registered. If you want to add a "getter" for your block use:

SearchClient.Instance.Conventions.UnifiedSearchRegistry.DefaultProjectionBuilder.ProjectOriginalObjectGetterFrom<MyBlock>(b => () => GetBlock((IContent) b).ContentLink));

static MyBlock GetBlock(ContentReference contentLink)
        {
            var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
            return contentRepository.Get<MyBlock>(contentLink);
        }

    


 

#72315
Jun 13, 2013 9:38
Vote:
 

Hi Adam,

This is because we do not do any projections for blocks out of the box. This is ofc possible to extend. I will provide you with some code so you hopefully can make it work.

First you need to add the convention for the projection:

instance.Conventions.UnifiedSearchRegistry
                .Add<BlockData>()
                .PublicSearchFilter(c => c.BuildFilter<BlockData>().FilterOnReadAccess())
                .CustomizeProjection(CustomizeProjectionForBlockData);

 

After that you need to add the extension methods to make that work:

private static HitProjectionBuilder CustomizeProjectionForBlockData(HitProjectionBuilder projection)
        {
            return projection.ProjectOriginalObjectGetterFrom<BlockData>(b => () => GetBlock(new PageReference(((IContent)b).ContentLink.ID, ((IContent)b).ContentLink.ProviderName)));
        }

  And:

private static BlockData GetBlock(ContentReference contentLink)
        {
            var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
            return contentRepository.Get<BlockData>(contentLink);
        }

    

Hope that will help you on the way. And if there is anything else just let me know

#72316
Jun 13, 2013 9:45
Vote:
 

Thanks Guys - Marcus, I am trying your example. I am having a compile issue with "c.BuildFilter<BlockData>".

'EPiServer.Find.IClient' does not contain a definition for 'BuildFilter' and no extension method 'BuildFilter' accepting a first argument of type 'EPiServer.Find.IClient' could be found (are you missing a using directive or an assembly reference?)

Is this an extnetion already included in Find or one I need to create it?

#72318
Jun 13, 2013 9:57
Vote:
 

Hi,

Yeah the extension already exist. It resides in the namespace EPiServer.Find in a class called ClientExtensions. Myabe need to add a using?

/Marcus

#72320
Jun 13, 2013 10:01
Vote:
 

Perfect - That was it! Thanks Marcus

#72327
Jun 13, 2013 10:33
Vote:
 

Hi,

I thought I'd just add some info in case someone else stumbles upon this thread.

Blocks aren't included in unified search out of the box as they typically shouldn't show up individually in search results (there's nothing to link to etc). They can however be included on their "host" pages making them searchable inside of the pages that they are used on. See here for more info.

With that said there are of course use cases where one would want to include blocks in unified search, like in this thread. If blocks, or any other type is included it may be cases where you want to exclude them from certain search functionality. That can be done using a filter, like:

Filter(x => !x.MatchTypeHiearchy(typeof(BlockData))

#72336
Jun 13, 2013 12:22
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.