Variant as Child of Parent Strategy
This strategy relies on the fact that variants will be indexed as children for their parent product/bundle/package using the hawk_child_attributes
JSON property.
The properties decorated with [IncludeInHawksearch]
attribute will be the ones that are indexed for each variant residing below hawk_child_attributes
. The product itself is, of course, indexed.
To use this indexing strategy, set variantindexingstrategy to “VariantAsChildOfParent“ in Web.config.
<hawksearch ...
variantindexingstrategy="VariantAsChildOfParent"
</hawksearch>
Example:
[IncludeInHawksearch]
public virtual string Color { get; set; }
The “Color” property will be included in the variant indexed under hawk_child_attributes
.
Convention
Every field that will be equivalent to a variant property shall be prefixed by “Child_” in Hawksearch. Also, it will have the “Is Child Field?” flag set to “ON”
Example:
For →
[IncludeInHawksearch]
public virtual string Color { get; set; }
we have Child_Color
For →
[IncludeInHawksearch]c
public virtual string Size { get; set; }
we have Child_Size
Default Fields
These fields are always included in indexing (can be found here)
Child_DisplayName
Child_Code
Child_Url
Considerations
Variant Indexing is unavailable under this strategy.
AddHawksearchVariantIndexing
will throw aNotSupportedException
if attempted to be used inside chain initialization. Also,VariantsIndexingHandler
andVariantsIncrementalIndexingHandler
pipes will be rendered useless and throw exceptions.Price and inventory indexing options from Web.config will have no effect, because Variant Indexing is unavailable.
Indexing Setup Example: Optimizely Foundation
A full version of the HawksearchInitialization
class used to set up indexing on the Optimizely Foundation solution can be found below:
using EPiServer.Commerce.Catalog.ContentTypes;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using Foundation.Features.CatalogContent.Bundle;
using Foundation.Features.CatalogContent.Package;
using Foundation.Features.CatalogContent.Product;
using Foundation.Features.CatalogContent.Variation;
using Foundation.Features.Hawksearch.Indexing.Pipes;
using Foundation.Features.Hawksearch.Indexing.Pipes.Pages;
using Foundation.Features.Locations.LocationItemPage;
using Optimizely.Hawksearch.Connector.Contracts;
using Optimizely.Hawksearch.Connector.Core;
using Optimizely.Hawksearch.Connector.Handlers;
using Optimizely.Hawksearch.Connector.Handlers.Category;
using Optimizely.Hawksearch.Connector.Handlers.Page;
using Optimizely.Hawksearch.Connector.Handlers.Product;
using Optimizely.Hawksearch.Connector.Initialization;
using StructureMap;
namespace Foundation.Features.Hawksearch.Indexing
{
[InitializableModule]
[ModuleDependency(typeof(BasicHawksearchInitialization))]
public class HawksearchInitialization : IConfigurableModule
{
internal Injected<IContainer> Container;
public void ConfigureContainer(ServiceConfigurationContext context)
{
var container = context.StructureMap();
container.AddHawksearchCategoryIndexing<NodeContent>();
container.AddHawksearchProductIndexing<GenericProduct, GenericVariant>()
.ExtendProductIndexing<GenericProduct, EntriesImagePipe<GenericProduct>>()
.ExtendProductIndexing<GenericProduct, GenericProductAttributesPipe>();
container.AddHawksearchBundleIndexing<GenericBundle, GenericVariant>();
container.AddHawksearchPackageIndexing<GenericPackage, GenericVariant>();
container.AddHawksearchPageIndexing<LocationItemPage>()
.ExtendPageIndexing<LocationItemPage, FoundationPageAttributesPipe<LocationItemPage>>()
.ExtendPageIndexing<LocationItemPage, LocationItemPageAttributesPipe>();
container.AddHawksearchPageIndexing<StandardPage.StandardPage>()
.ExtendPageIndexing<StandardPage.StandardPage, FoundationPageAttributesPipe<StandardPage.StandardPage>>()
.ExtendPageIndexing<StandardPage.StandardPage, StandardPageAttributesPipe>();
}
public void Initialize(InitializationEngine context)
{
Container.Service.Configure(config =>
{
config.For<IFullIndexingChain>().Add(() => FullIndexingChain(Container.Service))
.Transient();
config.For<IIncrementalIndexingChain>().Add(() => IncrementalIndexingChain(Container.Service))
.Transient();
});
}
private IndexingChain FullIndexingChain(IContainer container)
{
return new IndexingChain(container)
.AddHandler<DeletePreviousIndexHandler>()
.AddHandler<CreateIndexHandler>()
.AddHandler<CategoriesIndexingHandler<NodeContent>>()
.AddHandler<HierarchyRebuildHandler>()
.AddHandler<ProductsIndexingHandler<GenericProduct>>()
.AddHandler<BundlesIndexingHandler<GenericBundle>>()
.AddHandler<PackagesIndexingHandler<GenericPackage>>()
.AddHandler<PagesIndexingHandler<LocationItemPage>>()
.AddHandler<PagesIndexingHandler<StandardPage.StandardPage>>()
.AddHandler<RebuildIndexHandler>()
.AddHandler<SetCurrentIndexHandler>();
}
private IndexingChain IncrementalIndexingChain(IContainer container)
{
return new IndexingChain(container)
.AddHandler<GetCurrentIndexHandler>()
.AddHandler<CategoriesIncrementalIndexingHandler<NodeContent>>()
.AddHandler<CategoriesDeletionHandler>()
.AddHandler<HierarchyRebuildHandler>()
.AddHandler<CategoriesCascadeIndexingHandler>()
.AddHandler<ProductsIncrementalIndexingHandler<GenericProduct>>()
.AddHandler<BundlesIncrementalIndexingHandler<GenericBundle>>()
.AddHandler<PackagesIncrementalIndexingHandler<GenericPackage>>()
.AddHandler<PagesIncrementalIndexingHandler<LocationItemPage>>()
.AddHandler<PagesIncrementalIndexingHandler<StandardPage.StandardPage>>()
.AddHandler<EntriesDeletionHandler>()
.AddHandler<PagesDeletionHandler>()
.AddHandler<RebuildIndexHandler>();
}
public void Uninitialize(InitializationEngine context)
{
}
}
}