Search	add a custom field to a product document
32 Questions
1 Views

Search add a custom field to a product document

Created by
@SupportedAstatine4145

Podcast Beta

Play an AI-generated podcast conversation about this lesson

Questions and Answers

What is the default configuration when using Elasticsearch version 7.10?

  • Search rebuild version 1
  • No specific version
  • Search rebuild version 3
  • Search rebuild version 2 (correct)
  • Which role is required to opt into search rebuild version 2 in the Admin Console?

  • ISC_Implementer (correct)
  • System Administrator
  • Product Manager
  • Search Developer
  • What should you do to optimize the performance of a custom extension during the search rebuild process?

  • Use a JOIN operation to gather related data
  • Cache all results in memory
  • Select only the needed columns from the database (correct)
  • Use a full database query retrieving all fields
  • What is the recommended method to gather data for modifying base results in the search rebuild process?

    <p>Utilize a PrepareToRetrieveIndexableProducts extension</p> Signup and view all the answers

    What must be done after modifying the IndexableProducts property in the pipeline sequence?

    <p>Create a new pipeline after the base code</p> Signup and view all the answers

    What does C#'s 'iterator methods' feature allow you to do in the context of modifying IndexableProducts?

    <p>Yield modified results while enumerating</p> Signup and view all the answers

    What happens if you try to override base code in version 2 of the search rebuild process?

    <p>It can cause performance issues</p> Signup and view all the answers

    What happens to support for search rebuild version 1?

    <p>It is no longer supported</p> Signup and view all the answers

    What should you avoid doing inside your iteration to ensure good performance?

    <p>Running database queries or network activities</p> Signup and view all the answers

    What is the purpose of extending CreateElasticsearchProductResult?

    <p>To modify a record for Elasticsearch or suppress it</p> Signup and view all the answers

    Which namespace is used for extending the ElasticsearchProduct class?

    <p>Extensions.Search.Elasticsearch.DocumentTypes.Product</p> Signup and view all the answers

    What is required to create a custom property in the extended ElasticsearchProduct?

    <p>Inheriting from ElasticsearchProduct and adding a field</p> Signup and view all the answers

    What should be gathered in the PrepareToRetrieveIndexableProducts extension?

    <p>Essential data needed for customization</p> Signup and view all the answers

    What is the role of the Order property in the PrepareToRetrieveIndexableProducts class?

    <p>To specify the processing priority within a pipeline</p> Signup and view all the answers

    Which of the following is true about the constructor of the ElasticsearchProductCustom class?

    <p>It replicates all properties from the base class.</p> Signup and view all the answers

    What type of data handling is discouraged within the method discussed?

    <p>Invoking external services or databases</p> Signup and view all the answers

    What is being prepared in the method Execute of PrepareToRetrieveIndexableProductsResult?

    <p>Indexable products prepared for retrieval</p> Signup and view all the answers

    How does the GroupBy function work in the Execute method?

    <p>It groups order lines by ProductId.</p> Signup and view all the answers

    What is the purpose of the MyCustomField in the CreateElasticsearchProductResult?

    <p>To represent the total count of indexable products.</p> Signup and view all the answers

    Where does the ExtendElasticsearchProduct class fit in the pipeline?

    <p>It is situated after the FormSortOrder pipe.</p> Signup and view all the answers

    What happens if the TryGetValue method does not find a matching ProductId?

    <p>MyCustomField remains unchanged.</p> Signup and view all the answers

    What type of data structure is used to store the indexed products preparation result?

    <p>A Dictionary</p> Signup and view all the answers

    What impact does the new custom field have in the search output?

    <p>It influences the relevance scoring of search results.</p> Signup and view all the answers

    What is the primary role of the Execute method within the ExtendElasticsearchProduct class?

    <p>To enhance product data with additional fields.</p> Signup and view all the answers

    What does the Order property in the FormCustomSortOrder class indicate?

    <p>The execution priority of the pipeline</p> Signup and view all the answers

    Under what condition will the result.SortOrderFields be set in the Execute method?

    <p>When SortBy is not Relevance and SearchCriteria is not blank</p> Signup and view all the answers

    Which pipeline is responsible for building filters for product search in various categories?

    <p>RunProductSearch</p> Signup and view all the answers

    In the SortOrderField instantiation, what does the second 'true' parameter signify?

    <p>The field is sortable</p> Signup and view all the answers

    What type of search does the RunProductFacetSearch pipeline perform?

    <p>Faceted searches over various attributes</p> Signup and view all the answers

    What is the purpose of the FormRestrictionGroupFilter in relation to the product search?

    <p>To apply restrictions on product visibility</p> Signup and view all the answers

    Which of the following is NOT mentioned as a feature of the RunProductSearch pipeline?

    <p>Multi-value field indexing</p> Signup and view all the answers

    What does MyCustomField represent in the context of the SortOrderField?

    <p>An optional field for added sorting capabilities</p> Signup and view all the answers

    Study Notes

    Search Rebuild V2

    • Search rebuild version 2 increases index build speed and performance
    • It's recommended to upgrade to version 2
    • Some customization may require extra effort to ensure they properly function

    Opting in to version 2

    • Users with the ISC_Implementer role can opt in to version 2
    • Go to Administration > System > Settings
    • Click the Search tab
    • Select Version 2 on the Build Version dropdown
    • Click Save

    Modifying the Search Build

    • Use a PrepareToRetrieveIndexableProducts extension to gather data for modifying base results
      • Attach data to the RetrieveIndexableProductsPreparation property of the result
    • For best performance, use a custom entity framework database query with a general form of .ToDictionary(record => record.ProductId)
    • Store the dictionary in RetrieveIndexableProductsPreparation and use .TryGetValue to look up product extension data
    • Select only needed columns from the database
    • Create a new pipeline after the base code sequence in the pipeline that modifies the IndexableProducts property
    • You cannot override base code in version 2, doing so in version 1 causes performance and compatibility issues
    • The data in PrepareToRetrieveIndexableProducts is available in the RetrieveIndexableProductsPreparation property
    • Use iterator methods to add, remove, or modify the content of IndexableProducts by enumerating it in your extension and yielding the modified results
    • Do not perform database queries or other network activity inside the iteration, gather the data in PrepareToRetrieveIndexableProducts and use it in the pipeline
    • If you are not adding new records, you may be able to use an extension of CreateElasticsearchProductResult alone
    • Use CreateElasticsearchProductResult extensions to modify a record destined for Elasticsearch or suppress it by returning null
    • Extend the record by inheriting ElasticsearchProduct and adding custom fields
    • Do not do any database queries or other network activity inside this method

    Extension example code

    Adding a custom field to Elasticsearch product

    • Extend ElasticsearchProduct with a custom property
    • C# Elasticsearch v5*
    namespace Extensions.Search.Elasticsearch.DocumentTypes.Product
    {
      using Insite.Search.Elasticsearch.DocumentTypes.Product;
      using Nest;
    
     [ElasticsearchType(Name = "product")]
     public class ElasticsearchProductCustom : ElasticsearchProduct
     {
         public ElasticsearchProductCustom(ElasticsearchProduct source)
             : base(source) 
         {
         }
    
         [Keyword(Name = "myCustomField ", Index = true)]
         public int MyCustomField { get; set; }
     }
    }
    
    • C# Elasticsearch v7*
    namespace Extensions.Search.Elasticsearch.DocumentTypes.Product
    {
      using Insite.Search.Elasticsearch.DocumentTypes.Product;
      using Nest;
    
     [ElasticsearchType(Name = "product")]
     public class ElasticsearchProductCustom : ElasticsearchProduct
     {
         public ElasticsearchProductCustom(ElasticsearchProduct source)
             : base(source) 
         {
         }
    
         [Keyword(Name = "myCustomField ", Index = true)]
         public int MyCustomField { get; set; }
     }
    }
    

    Gathers Data for customization

    • Gather data in an extension of PrepareToRetrieveIndexableProducts
    • C# Elasticsearch v5*
    namespace Extensions.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Pipes.PrepareToRetrieveIndexableProducts
    {
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Plugins.Pipelines;
      using Insite.Data.Entities;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Parameters;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Results;
      using System.Linq;
    
     public sealed class PrepareToRetrieveIndexableProducts : IPipe
     {
         public int Order => 0; 
         public PrepareToRetrieveIndexableProductsResult Execute(IUnitOfWork unitOfWork, PrepareToRetrieveIndexableProductsParameter parameter, PrepareToRetrieveIndexableProductsResult result)
         {
             result.RetrieveIndexableProductsPreparation = unitOfWork.GetRepository().GetTableAsNoTracking().Where(order => order.Status == "Submitted").SelectMany(order => order.OrderLines).GroupBy(orderLine => orderLine.ProductId).ToDictionary(group => group.Key, group => group.Count());
             return result;
         }
     }
    }
    
    • C# Elasticsearch v7*
    namespace Extensions.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Pipes.PrepareToRetrieveIndexableProducts
    {
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Plugins.Pipelines;
      using Insite.Data.Entities;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Parameters;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Results;
      using System.Linq;
    
     public sealed class PrepareToRetrieveIndexableProducts : IPipe
     {
         public int Order => 0; 
         public PrepareToRetrieveIndexableProductsResult Execute(IUnitOfWork unitOfWork, PrepareToRetrieveIndexableProductsParameter parameter, PrepareToRetrieveIndexableProductsResult result)
         {
             result.RetrieveIndexableProductsPreparation = unitOfWork.GetRepository().GetTableAsNoTracking().Where(order => order.Status == "Submitted").SelectMany(order => order.OrderLines).GroupBy(orderLine => orderLine.ProductId).ToDictionary(group => group.Key, group => group.Count());
             return result;
         }
     }
    }
    

    Extract data and apply it to the extended record

    • Extract data from the preparation result in CreateElasticsearchProductResult
    • C# Elasticsearch v5*
    namespace Extensions.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Pipes.CreateElasticsearchProduct
    {
      using System;
      using System.Collections.Generic;
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Plugins.Pipelines;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Parameters;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Results;
    
     public sealed class ExtendElasticsearchProduct : IPipe
     {
         public int Order => 150;
         public CreateElasticsearchProductResult Execute(IUnitOfWork unitOfWork, CreateElasticsearchProductParameter parameter, CreateElasticsearchProductResult result)
         {
             var elasticsearchProductCustom = new ElasticsearchProductCustom(result.ElasticsearchProduct);
             if (((Dictionary)parameter.RetrieveIndexableProductsPreparation).TryGetValue(elasticsearchProductCustom.ProductId, out var count))
             {
                 elasticsearchProductCustom.MyCustomField = count;
             }
             result.ElasticsearchProduct = elasticsearchProductCustom;
             return result;
         }
     }
    }
    
    • C# Elasticsearch v7*
    namespace Extensions.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Pipes.CreateElasticsearchProduct
    {
      using System;
      using System.Collections.Generic;
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Plugins.Pipelines;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Parameters;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Index.Pipelines.Results;
    
     public sealed class ExtendElasticsearchProduct : IPipe
     {
         public int Order => 150;
         public CreateElasticsearchProductResult Execute(IUnitOfWork unitOfWork, CreateElasticsearchProductParameter parameter, CreateElasticsearchProductResult result)
         {
             var elasticsearchProductCustom = new ElasticsearchProductCustom(result.ElasticsearchProduct);
             if (((Dictionary)parameter.RetrieveIndexableProductsPreparation).TryGetValue(elasticsearchProductCustom.ProductId, out var count))
             {
                 elasticsearchProductCustom.MyCustomField = count;
             }
             result.ElasticsearchProduct = elasticsearchProductCustom;
             return result;
         }
     }
    }
    

    Use the new field

    • The code adds a new field to Elasticsearch index product documents
    • This data can be used in query pipelines
    • An example is using the new field to influence the sort order of results by adding a pipe in the RunProductSearch pipeline
    • This pipe runs after the FormSortOrder pipe which modifies the SortOrderFields field on RunProductSearchResult when the user is on a category page using the default Relevance sort order
    • C# Elasticsearch v5*
    namespace Extensions.Plugins.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Pipes.RunProductSearch
    {
      using System;
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Plugins.Pipelines;
      using Insite.Core.Plugins.Search;
      using Insite.Search.Elasticsearch.DocumentTypes.Product;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Parameters;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Results;
    
     public class FormCustomSortOrder : IPipe
     {
         public int Order => 310;
         public RunProductSearchResult Execute(
             IUnitOfWork unitOfWork,
             RunProductSearchParameter parameter,
             RunProductSearchResult result)
         {
             if (result.SortOrderFields == null)
             {
                 return result;
             }
             if (parameter.ProductSearchParameter.SortBy != SortOrderType.Relevance ||
                 parameter.ProductSearchParameter.SearchCriteria.IsNotBlank() ||
                 parameter.ProductSearchParameter.SearchCriteria.IsNotBlank())
             {
                 return result;
             }
             result.SortOrderFields = new[]
             {
                 new SortOrderField(nameof(ElasticsearchProduct.SortOrder).ToCamelCase(), true, true),
                 new SortOrderField(nameof(ElasticsearchProductCustom.MyCustomField).ToCamelCase(), true, true),
                 new SortOrderField(nameof(ElasticsearchProduct.ShortDescriptionSort).ToCamelCase())
             };
             return result;
         }
     }
    }
    
    • C# Elasticsearch v7*
    namespace Extensions.Plugins.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Pipes.RunProductSearch
    {
      using System;
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Plugins.Pipelines;
      using Insite.Core.Plugins.Search;
      using Insite.Search.Elasticsearch.DocumentTypes.Product;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Parameters;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Results;
    
     public class FormCustomSortOrder : IPipe
     {
         public int Order => 310;
         public RunProductSearchResult Execute(
             IUnitOfWork unitOfWork,
             RunProductSearchParameter parameter,
             RunProductSearchResult result)
         {
             if (result.SortOrderFields == null)
             {
                 return result;
             }
             if (parameter.ProductSearchParameter.SortBy != SortOrderType.Relevance ||
                 parameter.ProductSearchParameter.SearchCriteria.IsNotBlank() ||
                 parameter.ProductSearchParameter.SearchCriteria.IsNotBlank())
             {
                 return result;
             }
             result.SortOrderFields = new[]
             {
                 new SortOrderField(nameof(ElasticsearchProduct.SortOrder).ToCamelCase(), true, true),
                 new SortOrderField(nameof(ElasticsearchProductCustom.MyCustomField).ToCamelCase(), true, true),
                 new SortOrderField(nameof(ElasticsearchProduct.ShortDescriptionSort).ToCamelCase())
             };
             return result;
         }
     }
    }
    
    • Shared Search*
    namespace Extensions.Plugins.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Pipes.RunProductSearch
    {
      using System;
      using Insite.Core.Interfaces.Data;
      using Insite.Core.Plugins.Pipelines;
      using Insite.Core.Plugins.Search;
      using Insite.Search.Elasticsearch.DocumentTypes.Product;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Parameters;
      using Insite.Search.Elasticsearch.DocumentTypes.Product.Query.Pipelines.Results;
    
     public class FormCustomSortOrder : IPipe
     {
         public int Order => 310;
         public RunProductSearchResult Execute(
             IUnitOfWork unitOfWork,
             RunProductSearchParameter parameter,
             RunProductSearchResult result)
         {
             if (result.SortOrderFields == null)
             {
                 return result;
             }
             if (parameter.ProductSearchParameter.SortBy != SortOrderType.Relevance ||
                 parameter.ProductSearchParameter.SearchCriteria.IsNotBlank() ||
                 parameter.ProductSearchParameter.SearchCriteria.IsNotBlank())
             {
                 return result;
             }
             result.SortOrderFields = new[]
             {
                 new SortOrderField(nameof(ElasticsearchProduct.SortOrder).ToCamelCase(), true, true),
                 new SortOrderField(nameof(ElasticsearchProductCustom.MyCustomField).ToCamelCase(), true, true),
                 new SortOrderField(nameof(ElasticsearchProduct.ShortDescriptionSort).ToCamelCase())
             };
             return result;
         }
     }
    }
    

    Available pipelines

    • RunProductSearch - The main product query builder
    • FormProductFilter builds filter for product search over category, language, and attributes
    • RunProductFacetSearch performs faceted searches over brand, product line, and category
    • RunBrandSearch searches for brands within the product index
    • FormRestrictionGroupFilter builds the restriction group filter for the FormProductFilter pipeline

    Note

    • The Optimizely Dogfood sample repository on Github includes an example of adding a multi-value field to the index and using it to filter products based on warehouse stock

    Studying That Suits You

    Use AI to generate personalized quizzes and flashcards to suit your learning preferences.

    Quiz Team

    Related Documents

    Description

    This quiz covers the enhancements introduced in Search Rebuild Version 2, including index build speed and performance improvements. It guides users on how to opt into the new version and modify search build parameters effectively. Test your knowledge on the recommended practices and settings for optimizing search functionality.

    More Like This

    Use Quizgecko on...
    Browser
    Browser