Search in Dawiso is powered by Elasticsearch. Packages define which object types and attributes are indexed, how queries are constructed, and what the search UI presents to users.

Search configuration consists of three asset types that work together:

ComponentAsset typeControls
Search indexessearchIndexesWhat gets indexed — which object types and attributes map to Elasticsearch fields
Search queriessearchQueriesHow searches execute — filters, field boosting, result ordering
Search formssearchFormsWhat users see — filter panels, facet lists, result columns

Each component can be defined independently, but a functional search requires all three to be configured for the target object types.

Search Indexes

A search index maps an object type and its attributes to Elasticsearch fields. The index definition specifies which attributes are included and how each attribute value is analyzed and stored.

{
  "searchIndexes": [
    {
      "key": "cust_recipe_index",
      "objectTypeKey": "cust_recipe",
      "attributes": [
        { "key": "core#name" },
        { "key": "core#description" },
        { "key": "cust_category" },
        { "key": "cust_rating" }
      ]
    }
  ]
}

The attributes listed in the index must have appropriate search features to be indexed. An attribute without any is_search_type_* feature is skipped during indexing even if it appears in the index definition.

Attribute Search Features

Search features on attribute types control how Elasticsearch processes their values.

FeatureElasticsearch behaviorUse case
is_search_type_textFull-text analysis with stemming and tokenizationDescriptions, notes, long text fields
is_search_type_termStored as exact keyword, supports aggregationsCategories, statuses, codes, codetable values
is_search_type_boolStored as boolean, supports boolean aggregationYes/no flags, toggles
is_token_textTokenized as keywords without stemmingTags, labels, multi-word identifiers
is_search_default_result_textIncluded in search result snippet previewKey identifiers, names, short descriptions

Feature Combinations

Attributes can carry multiple search features simultaneously:

  • is_search_type_text + is_search_default_result_text — full-text searchable and shown in result snippets
  • is_search_type_term + is_search_default_result_text — exact-match filterable and shown in results
  • is_search_type_text + is_search_type_term — full-text searchable and available as a facet filter
Warning

An attribute without any is_search_type_* feature is not indexed by Elasticsearch. Adding a search feature to an existing attribute requires a full reindex for the feature to take effect.

Warning

Facets require is_search_type_term, not is_search_type_text. Using is_search_type_text on a facet field produces per-token facets (each word becomes a separate facet value), not whole-value facets. For dropdown/filter facets, always use is_search_type_term.

Tokenization Configuration

Tokenization controls how text values are split into searchable tokens before indexing.

Default Behavior

Attributes with is_search_type_text use the standard analyzer: Unicode text segmentation, lowercase normalization, and language-specific stemming. This handles most European languages well.

Custom Tokenization

Custom tokenization configuration overrides the default analyzer for specific attributes. Available options:

  • Stemming — reduces words to their root form (“running” → “run”). Enabled by default for is_search_type_text.
  • Stop words — common words excluded from the index (“the”, “and”, “is”). Language-specific stop word lists are applied by default.
  • Character filters — transform characters before tokenization. Strip HTML tags, normalize accented characters, replace special characters.
Tip

After changing tokenization configuration on any attribute, a full reindex is required. The new tokenization rules apply only to documents indexed after the change.

Search Queries

Search queries define how user input translates into Elasticsearch requests. Each query specifies the target index, field weights, and default filters.

{
  "searchQueries": [
    {
      "key": "cust_recipe_search",
      "searchIndexKey": "cust_recipe_index",
      "fields": [
        { "attributeKey": "core#name", "boost": 3.0 },
        { "attributeKey": "core#description", "boost": 1.0 },
        { "attributeKey": "cust_category", "boost": 2.0 }
      ],
      "defaultSort": "relevance"
    }
  ]
}

Field Boosting

The boost value multiplies the relevance score for matches in that field. Higher boost values push matches in that field to the top of results.

Boost rangeTypical use
3.0–5.0Primary identifiers (name, title, code)
1.5–2.5Secondary identifiers (category, type, classification)
1.0Standard content (description, notes)
0.5–0.9Low-priority fields (internal comments, metadata)

Boost values are relative within a single query. A field with boost 3.0 is three times more influential than a field with boost 1.0 in the same query.

Result Ordering

Results can be ordered by:

  • Relevance — Elasticsearch’s _score based on TF-IDF and field boosts
  • Date — chronological or reverse-chronological by a date attribute
  • Alphabetical — sorted by a text attribute value
  • Custom — sorted by a numeric or term attribute

Search Forms

Search forms define the UI layer: which filters appear in the sidebar, which facets are available, and what columns display in the result list.

{
  "searchForms": [
    {
      "key": "cust_recipe_form",
      "searchQueryKey": "cust_recipe_search",
      "filters": [
        {
          "attributeKey": "cust_category",
          "displayType": "facet",
          "collapsed": false
        },
        {
          "attributeKey": "cust_rating",
          "displayType": "range",
          "collapsed": true
        }
      ],
      "resultColumns": [
        { "attributeKey": "core#name" },
        { "attributeKey": "cust_category" },
        { "attributeKey": "cust_rating" }
      ]
    }
  ]
}

Filter Display Types

TypeRenders asRequires
facetCheckbox list with countsis_search_type_term on the attribute
rangeMin/max slideris_number and is_search_type_term on the attribute
booleanToggle switchis_search_type_bool on the attribute
date_rangeDate picker pairis_date and is_search_type_term on the attribute
textFree-text inputis_search_type_text on the attribute

Facets use is_search_type_term attributes to create filter-and-count panels. Elasticsearch runs an aggregation query on the term field, returning each unique value and the number of matching documents.

Facet behavior:

  • Selecting a facet value narrows the result set to objects with that value.
  • Multiple facet values within the same attribute combine with OR logic (any match).
  • Facet values across different attributes combine with AND logic (all must match).
  • Facet counts update dynamically as filters are applied.

Attributes intended for faceted search must use is_search_type_term, not is_search_type_text. Full-text analyzed fields produce too many token-level facet entries to be usable.

Elasticsearch Reindex

Package installation does not trigger an automatic Elasticsearch reindex. New or modified search indexes exist in the configuration but contain no indexed documents until a reindex runs.

When to Reindex

ChangeReindex required
New package with search indexes installedYes
Search feature added to an existing attributeYes
Tokenization configuration changedYes
Search query boost values changedNo (applies at query time)
Search form filters rearrangedNo (UI-only change)
New objects created after index existsNo (indexed on creation)

How to Reindex

  1. Navigate to Settings > Search.
  2. Select the indexes to reindex (or choose “Reindex All”).
  3. Start the reindex process.

Reindex duration depends on the number of indexed objects. Large datasets (100k+ objects) may take several minutes. Search queries against the affected indexes return partial results during reindex.

Warning

New search indexes return empty results until the first reindex completes. This is the most common cause of “search is broken” reports after package installation.

Complete Configuration Example

A package that makes cust_recipe objects fully searchable:

Attribute types with search features:

{
  "attributeTypes": [
    {
      "key": "cust_category",
      "name": "Category",
      "features": [
        { "key": "is_search_type_term", "value": true },
        { "key": "is_search_default_result_text", "value": true }
      ]
    },
    {
      "key": "cust_instructions",
      "name": "Instructions",
      "features": [
        { "key": "is_html", "value": true },
        { "key": "is_search_type_text", "value": true },
        { "key": "is_search_default_result_text", "value": true }
      ]
    }
  ]
}

Search index mapping the object type:

{
  "searchIndexes": [
    {
      "key": "recipe_index",
      "objectTypeKey": "cust_recipe",
      "attributes": [
        { "key": "core#name" },
        { "key": "cust_category" },
        { "key": "cust_instructions" }
      ]
    }
  ]
}

Search query with field boosting:

{
  "searchQueries": [
    {
      "key": "recipe_query",
      "searchIndexKey": "recipe_index",
      "fields": [
        { "attributeKey": "core#name", "boost": 3.0 },
        { "attributeKey": "cust_category", "boost": 2.0 },
        { "attributeKey": "cust_instructions", "boost": 1.0 }
      ]
    }
  ]
}

Search form with facets and result columns:

{
  "searchForms": [
    {
      "key": "recipe_form",
      "searchQueryKey": "recipe_query",
      "filters": [
        {
          "attributeKey": "cust_category",
          "displayType": "facet",
          "collapsed": false
        }
      ],
      "resultColumns": [
        { "attributeKey": "core#name" },
        { "attributeKey": "cust_category" },
        { "attributeKey": "cust_instructions" }
      ]
    }
  ]
}

After installing this package, trigger a reindex for the recipe_index to populate Elasticsearch with existing cust_recipe objects.

Gotchas

Warning

Missing search features = not indexed. An attribute listed in a search index but lacking any is_search_type_* feature is silently skipped during indexing. The attribute appears in the configuration but returns no search results. Always verify that indexed attributes have the appropriate search feature.

Warning

Reindex is not automatic. Installing a package with new search indexes does not trigger a reindex. Forgetting this step is the single most common cause of empty search results after installation. Prefer core search queries for standard use cases. Create custom queries only when core queries cannot express the required filtering pattern (e.g., specialized faceted search for specific object types).

Warning

Facets require term indexing. Using is_search_type_text for a facet attribute produces unusable results. Full-text analysis breaks the value into tokens, creating facet entries for each token instead of the complete value. Use is_search_type_term for all facet attributes.

Tip

Use is_search_type_text for fields where users search by content (descriptions, notes). Use is_search_type_term for fields where users filter by exact value (categories, statuses, codes).

Tip

After any package installation that includes search-related assets, add “trigger reindex” to the post-installation checklist. Treat it as a mandatory step, not an optional one.