Плагин поиска Elasticsearch для Medusa v2
Elasticsearch search plugin for Medusa v2. Provides automatic product and category indexing, full-text search, and admin sync capabilities powered by Elasticsearch.
1. Install the plugin in your Medusa project:
npm install medusa-plugin-elasticsearch2. Set environment variables in :
1ELASTIC_CLOUD_ID=your_cloud_id2ELASTIC_USER_NAME=your_username3ELASTIC_PASSWORD=your_passwordOr for a local Elasticsearch 9.x instance:
ELASTIC_NODE=http://localhost:92003. Register the plugin and module in :
1import { defineConfig } from "@medusajs/framework/utils"2
3export default defineConfig({4 // Register the plugin (loads subscribers, API routes, workflows, jobs)5 plugins: [6 {7 resolve: "medusa-plugin-elasticsearch",8 options: {},9 },10 ],11 // Register the Elasticsearch module12 modules: [13 {14 resolve: "medusa-plugin-elasticsearch/modules/elasticsearch",15 options: {16 config: {17 // Option A: Elastic Cloud18 cloud: {19 id: process.env.ELASTIC_CLOUD_ID,20 },21 auth: {22 username: process.env.ELASTIC_USER_NAME,23 password: process.env.ELASTIC_PASSWORD,24 },25 // Option B: Local instance26 // node: process.env.ELASTIC_NODE,27 },28 settings: {29 products: {30 // Optional: custom Elasticsearch mappings31 mappings: {32 properties: {33 id: { type: "keyword" },34 title: { type: "text" },35 description: { type: "text" },36 handle: { type: "keyword" },37 },38 },39 // Optional: custom index settings (analyzers, tokenizers)40 settings: {41 analysis: {42 tokenizer: {43 autocomplete: {44 type: "edge_ngram",45 min_gram: 2,46 max_gram: 10,47 token_chars: ["letter", "digit"],48 },49 },50 analyzer: {51 autocomplete_index: {52 type: "custom",53 tokenizer: "autocomplete",54 filter: ["lowercase"],55 },56 },57 },58 },59 },60 categories: {61 mappings: {62 properties: {63 id: { type: "keyword" },64 name: { type: "text" },65 handle: { type: "keyword" },66 description: { type: "text" },67 },68 },69 },70 },71 },72 },73 ],74})| Name | Description | Required |
|---|---|---|
| Elasticsearch client configuration (cloud, auth, node, etc.) | true | |
| Index configurations keyed by index name (, , or custom) | false |
| Name | Description | Required |
|---|---|---|
| Custom document transformer function | false | |
| Elasticsearch mapping configuration | false | |
| Elasticsearch index settings (analyzers, tokenizers, normalizers) | false |
POST /store/products/searchSearch products indexed in Elasticsearch. No authentication required.
Request body:
1{2 "q": "sweatshirt",3 "offset": 0,4 "limit": 20,5 "filter": {}6}POST /store/categories/searchSearch product categories. No authentication required.
Request body:
1{2 "q": "electronics",3 "offset": 0,4 "limit": 205}Response: Standard Elasticsearch search response with .
POST /admin/elasticsearch/syncTriggers a full reindex of all products and categories. Requires admin authentication (session, bearer, or API key).
Response:
1{2 "message": "Syncing products to Elasticsearch"3}The sync runs asynchronously, processing items in batches of 50.
The plugin automatically syncs on these events:
Products:
Categories:
A scheduled job runs daily at midnight to trigger a full reindex via the event.
Use the admin API endpoint or emit the event directly:
1const eventBus = container.resolve("event_bus")2await eventBus.emit({ name: "elasticsearch.sync", data: {} })The plugin exports workflows for direct use:
1import {2 syncProductsToElasticsearchWorkflow,3 deleteProductsFromElasticsearchWorkflow,4 syncCategoriesToElasticsearchWorkflow,5 deleteCategoriesFromElasticsearchWorkflow,6} from "medusa-plugin-elasticsearch/workflows"7
8// Sync specific products9await syncProductsToElasticsearchWorkflow(container).run({10 input: { ids: ["prod_01ABC"] },11})12
13// Sync specific categories14await syncCategoriesToElasticsearchWorkflow(container).run({15 input: { ids: ["pcat_01ABC"] },16})17
18// Delete from index19await deleteProductsFromElasticsearchWorkflow(container).run({20 input: { ids: ["prod_01ABC"] },21})22
23await deleteCategoriesFromElasticsearchWorkflow(container).run({24 input: { ids: ["pcat_01ABC"] },25})By default, products are indexed with a built-in transformer that flattens variant data, tags, categories, and collections. Categories are indexed with parent/children metadata. You can override either:
1{2 settings: {3 products: {4 transformer: (product) => ({5 id: product.id,6 title: product.title,7 description: product.description,8 handle: product.handle,9 thumbnail: product.thumbnail,10 }),11 },12 categories: {13 transformer: (category) => ({14 id: category.id,15 name: category.name,16 handle: category.handle,17 }),18 },19 },20}1src/2 admin/ # Admin UI extension3 lib/sdk.ts # Medusa JS SDK client4 routes/settings/elasticsearch/5 page.tsx # Settings page (sync + search testing)6 modules/elasticsearch/ # Elasticsearch module7 index.ts # Module definition (Module())8 service.ts # ES client service9 types.ts # Type definitions10 loaders/initialize.ts # Index initialization on startup11 subscribers/12 product-upsert.ts # Sync on product.created / product.updated13 product-deleted.ts # Remove on product.deleted14 category-upsert.ts # Sync on product-category.created / updated15 category-deleted.ts # Remove on product-category.deleted16 elasticsearch-sync.ts # Full reindex (products + categories)17 workflows/18 sync-products-to-elasticsearch.ts # Fetch + index products19 delete-products-from-elasticsearch.ts # Delete products from index20 sync-categories-to-elasticsearch.ts # Fetch + index categories21 delete-categories-from-elasticsearch.ts # Delete categories from index22 index.ts # Workflow exports23 api/24 middlewares.ts # Validation + admin auth25 store/products/search/ # POST /store/products/search26 store/categories/search/ # POST /store/categories/search27 admin/elasticsearch/sync/ # POST /admin/elasticsearch/sync28 jobs/29 elasticsearch-reindex.ts # Daily scheduled reindex30 utils/31 transformer.ts # Default product + category transformers32 types/33 index.ts # Public type exportsPlanned features for future releases:
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
MIT