Documentation Home

Module Installation

Steps to enable this module in your custom Broadleaf Commerce project

Steps

Step 1 Pull this dependency into your core/pom.xml:

<dependency>
    <groupId>org.broadleafcommerce</groupId>
    <artifactId>broadleaf-enterprise-search</artifactId>
</dependency>

This assumes that you are using the Broadleaf BOM that pins all version information. If not, you will need to also add a <version> qualifier

Data Changes

Schema Changes

To add all of the necessary database tables and columns for this module, please follow the Liquibase update documentation.

Admin Security Changes

The data in the following SQL file is required to establish Admin sections and permissions for this module:

classpath:/config/bc/sql/load_enterprise_search_admin_security.sql
classpath:/config/bc/sql/load_search_admin_security.sql

This file is automatically included if you have set blPU.hibernate.hbm2ddl.auto=create and you have not set import.sql.enabled=false in your properties files. If you are not using Hibernate's auto DDL process and are using Liquibase, you can add a new changeSet that references this file:

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
    <changeSet author="broadleaf" id="some-unique-id">
        <sqlFile path="config/bc/sql/load_enterprise_search_admin_security.sql" encoding="utf8" stripComments="true" />
        <sqlFile path="config/bc/sql/load_search_admin_security.sql" encoding="utf8" stripComments="true" />
    </changeSet>
</databaseChangeLog>

Finally, you can unpack the downloaded .jar file and look at the files in the config/bc/sql folder to execute this sql manually.

Data Changes

  1. Include the following dynamicField's and fieldType's to your solr schema.xml:

    <dynamicField name="*_tta" type="text_type_ahead" indexed="true" stored="true"/>
    <dynamicField name="*_tpa" type="text_partial" indexed="true" stored="true" />
    <dynamicField name="*_tsl" type="text_soundslike" indexed="true" stored="true" />
    <dynamicField name="*_tsy" type="text_synonyms" indexed="true" stored="true" />
    
    <dynamicField name="*_tmg" type="text_managed_en" indexed="true" stored="true" />
    <dynamicField name="*_tmg_en" type="text_managed_en" indexed="true" stored="true" />
    <dynamicField name="*_tmg_es" type="text_managed_es" indexed="true" stored="true" />
    <dynamicField name="*_tmg_fr" type="text_managed_fr" indexed="true" stored="true" />
    
    <fieldType name="text_partial" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.WordDelimiterFilterFactory"
                    generateWordParts="0"
                    generateNumberParts="0"
                    catenateWords="1"
                    catenateNumbers="1"
                    catenateAll="1"
                    splitOnCaseChange="1"
                    splitOnNumerics="0"
                    preserveOriginal="1"
            />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
            <filter class="solr.PorterStemFilterFactory"/>
            <filter class="solr.EdgeNGramFilterFactory" maxGramSize="20" minGramSize="2"/>
            <filter class="solr.PatternReplaceFilterFactory" pattern="([^\w\d\*æøåÆØÅ ])" replacement="" replace="all"/>
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.WordDelimiterFilterFactory"
                    generateWordParts="0"
                    generateNumberParts="0"
                    catenateWords="0"
                    catenateNumbers="0"
                    catenateAll="0"
                    splitOnCaseChange="0"
                    splitOnNumerics="0"
                    preserveOriginal="1"
            />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.PorterStemFilterFactory"/>
            <filter class="solr.PatternReplaceFilterFactory" pattern="([^\w\d\*æøåÆØÅ ])" replacement="" replace="all"/>
            <filter class="solr.PatternReplaceFilterFactory" pattern="^(.{20})(.*)?" replacement="$1" replace="all"/>
        </analyzer>
    </fieldType>
    
    <fieldType name="text_soundslike" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.DoubleMetaphoneFilterFactory" inject="true"/>
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.DoubleMetaphoneFilterFactory" inject="true"/>
        </analyzer>
    </fieldType>
    
    <fieldType name="text_synonyms" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
        </analyzer>
    </fieldType>
    <fieldType name="text_type_ahead" class="solr.TextField">
        <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.WordDelimiterFilterFactory"
                 generateWordParts="0"
                 generateNumberParts="0"
                 catenateWords="1"
                 catenateNumbers="1"
                 catenateAll="1"
                 splitOnCaseChange="1"
                 splitOnNumerics="0"
                 preserveOriginal="1"
            />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
            <filter class="solr.PorterStemFilterFactory"/>
            <filter class="solr.EdgeNGramFilterFactory" maxGramSize="20" minGramSize="2"/>
            <filter class="solr.PatternReplaceFilterFactory" pattern="([^\w\d\*æøåÆØÅ ])" replacement="" replace="all"/>
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.WordDelimiterFilterFactory"
                 generateWordParts="0"
                 generateNumberParts="0"
                 catenateWords="0"
                 catenateNumbers="0"
                 catenateAll="0"
                 splitOnCaseChange="0"
                 splitOnNumerics="0"
                 preserveOriginal="1"
            />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.PorterStemFilterFactory"/>
            <filter class="solr.PatternReplaceFilterFactory" pattern="([^\w\d\*æøåÆØÅ ])" replacement="" replace="all"/>
            <filter class="solr.PatternReplaceFilterFactory" pattern="^(.{20})(.*)?" replacement="$1" replace="all"/>
        </analyzer>
    </fieldType>
    
    <fieldType name="text_managed_en" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.ManagedStopFilterFactory" managed="en" />
            <filter class="solr.ManagedSynonymFilterFactory" managed="en" />
        </analyzer>
    </fieldType>
    
    <fieldType name="text_managed_es" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.ManagedStopFilterFactory" managed="es" />
            <filter class="solr.ManagedSynonymFilterFactory" managed="es" />
        </analyzer>
    </fieldType>
    
    <fieldType name="text_managed_fr" class="solr.TextField" positionIncrementGap="100">
        <analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
        </analyzer>
        <analyzer type="query">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.ManagedStopFilterFactory" managed="fr" />
            <filter class="solr.ManagedSynonymFilterFactory" managed="fr" />
        </analyzer>
    </fieldType>