This strategy relies on the fact that products and variants are indexed as separate documents inside Hawksearch. Their relationships are not expressed - it is not known which variants belong to which products in a parent-child fashion. The properties decorated with [IncludeInHawksearch]
attribute will be the ones that are indexed for each variant.
To use this indexing strategy, set variantindexingstrategy to “SeparateDocuments“ in Web.config.
<hawksearch ... variantindexingstrategy="SeparateDocuments" </hawksearch>
This should be the go-to strategy for variant-only catalogs.
For this strategy, it is important to add the Variant handlers and Variant Indexing extension method(s) in the initialization module:
container.AddHawksearchVariantIndexing<GenericVariant>() .ExtendVariantIndexing<GenericVariant, EntriesImagePipe<GenericVariant>>() .ExtendVariantIndexing<GenericVariant, GenericVariantAttributesPipe>() .ExtendVariantIndexing<GenericVariant, GenericVariantShippingPipe>(); private IndexingChain FullIndexingChain(IContainer container) { return new IndexingChain(container) .AddHandler<DeletePreviousIndexHandler>() ... .AddHandler<VariantsIndexingHandler<GenericVariant>>() ... ; } private IncrementalIndexingChain FullIndexingChain(IContainer container) { return new IndexingChain(container) .AddHandler<DeletePreviousIndexHandler>() ... .AddHandler<VariantsIncrementalIndexingHandler<GenericVariant>>() ... ; }
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.AddHawksearchVariantIndexing<GenericVariant>() .ExtendVariantIndexing<GenericVariant, EntriesImagePipe<GenericVariant>>() .ExtendVariantIndexing<GenericVariant, GenericVariantAttributesPipe>() .ExtendVariantIndexing<GenericVariant, GenericVariantShippingPipe>(); 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<VariantsIndexingHandler<GenericVariant>>() .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<VariantsIncrementalIndexingHandler<GenericVariant>>() .AddHandler<BundlesIncrementalIndexingHandler<GenericBundle>>() .AddHandler<PackagesIncrementalIndexingHandler<GenericPackage>>() .AddHandler<PagesIncrementalIndexingHandler<LocationItemPage>>() .AddHandler<PagesIncrementalIndexingHandler<StandardPage.StandardPage>>() .AddHandler<EntriesDeletionHandler>() .AddHandler<PagesDeletionHandler>() .AddHandler<RebuildIndexHandler>(); } public void Uninitialize(InitializationEngine context) { } } }