Indexing & Mapping Guide

Elasticsearch querying is very sophisticated, and many of the features rely on an appropriate mapping configured.

Updating index

Straightforward to update the index. See Updating indices.

Analyzer extensions

Out the box, elasticsearch uses the default standard analyzer. We extend the default analyzer to offer word delimiter, html strip and char mapping.

{
  "analysis": {
    "char_filter": {
       "replace": {
        "type": "mapping",
        "mappings": [
          "&=> and "
        ]
      }
    },
    "filter": {
      "word_delimiter" : {
        "type" : "word_delimiter",
        "split_on_numerics" : false,
        "split_on_case_change" : true,
        "generate_word_parts" : true,
        "generate_number_parts" : true,
        "catenate_all" : true,
        "preserve_original":true,
        "catenate_numbers":true
      }
    },
    "analyzer": {
      "default": {
        "type": "custom",
        "char_filter": [
          "html_strip",
          "replace"
        ],
        "tokenizer": "whitespace",
        "filter": [
            "lowercase",
            "word_delimiter"
        ]
      }
    }
  }
}

Searchkit Mapping best practices

Indexing fields for filtering & searching

Often you will want a field to be both searchable and appear as filters. A field will need to be indexed in 2 ways to achieve this, and we can make use of multi fields

Mapping example

{
  "movie" : {
    "properties" : {
      "genres" : {
        "type" : "string",
        "fields" : {          
          "raw" : {
            "type" : "string",
            "index" : "not_analyzed"
          }
        }
      }
    }
  }
}

This mapping will mean the genres field is indexed in 2 ways. The genres path will be analyzed by elastic search meaning it will be tokenized and have the standard stop words removed which is ideal for a free text search. The genres.raw path will be left untouched by Elasticsearch, Searchkit would use not_analyzed paths to power aggregated search components.

Component examples

Using the genres.raw field

<RefinementListFilter id="genres" title="Genres" field="genres.raw" operator="AND"/>

Using the field for searching using prefix

<SearchBox prefixQueryFields={["genres^1", "name^10"]}/>