Skip to main content

Local Search Filter

Full-text product and assortment search using MongoDB $text queries against the text collections. No external search service required.

Included in All Preset

Registered automatically by registerAllPlugins().

If you use the base preset or register plugins individually:

import { pluginRegistry } from '@unchainedshop/core';
import { LocalSearchPlugin } from '@unchainedshop/plugins/filters/local-search';

pluginRegistry.register(LocalSearchPlugin);

Adapter Details​

PropertyValue
Keyshop.unchained.filters.local-search
Order Index10
Sourcefilters/local-search

Behavior​

  • searchProducts() resolves queryString against the product texts collection via $text: { $search }, restricted to the already-selected product IDs when present.
  • searchAssortments() does the same against the assortment texts collection.
  • transformFilterSelector(): for global searches (a queryString without explicit filterIds), all active filters are returned instead of only assortment-linked ones.

The required text indexes are created automatically at startup:

CollectionIndexed fields (weight)
product_textstitle (8), subtitle (6), vendor (5), brand (4)
productswarehousing.sku, slugs
assortment_textstitle (8), subtitle (6)

Query strings follow MongoDB $text semantics (stemming, "exact phrase", -negation).

Query Examples​

query SearchProducts {
searchProducts(queryString: "running shoes") {
products {
_id
texts { title description }
}
filteredProductsCount
}
}
query SearchWithFilters {
searchProducts(
queryString: "organic cotton"
filterQuery: [
{ key: "category", value: "clothing" }
{ key: "size", value: "M" }
]
) {
products {
_id
texts { title }
}
filters {
filteredProductsCount
isSelected
options {
filteredProductsCount
isSelected
}
}
}
}
query SearchCategories {
searchAssortments(queryString: "summer collection") {
assortments {
_id
texts { title }
}
}
}

External Search Services​

For Algolia, Elasticsearch, etc., register a search callback with the factory functions instead of building a filter adapter by hand:

import {
registerAssortmentSearchFilter,
registerProductSearchFilter,
} from '@unchainedshop/core';

registerProductSearchFilter({
adapterId: 'algolia',
orderIndex: 10,
search: async ({ queryString }) => {
const { hits } = await productIndex.search(queryString, { hitsPerPage: 1000 });
return hits.map((hit) => hit.productId);
},
});

registerAssortmentSearchFilter({
adapterId: 'algolia',
orderIndex: 10,
search: async ({ queryString }) => {
const { hits } = await assortmentIndex.search(queryString);
return hits.map((hit) => hit.assortmentId);
},
});