Inspired by the dimitrov-adrian/directus-extension-searchsync, rewritten in TypeScript, and supporting Directus 10.
- ✅ MeiliSearch
- 🚧 ElasticSearch (coming soon)
- 🚧 Algolia (coming soon)
- Search for
Searchsync 2
extension in Directus Marketplace. - Click
Install Extension
. - Configure the extension.
Open the docker-compose.yml
file of your project and replace the image
option with a build
section:
# Before
image: directus/directus:10.x.y
# After
build:
context: ./
At the root of your project, create a Dockerfile
if one doesn't already exist, and add the following:
FROM directus/directus:10.x.y
USER root
RUN corepack enable
USER node
RUN pnpm install directus-extension-searchsync-2
docker compose build
docker compose up
Directus will automatically load the extension installed in the previous steps.
At the root of your project, create an extensions
folder if it doesn't already exist to house the extensions.
cd extensions
git clone https://github.com/dawid-napora/directus-extension-searchsync-2.git
Your folder structure should look like this:
extensions/
directus-extension-searchsync-2/
dist/
index.js
package.json
...
To build the extension, install dependencies and then run the build
script:
cd directus-extension-searchsync-2
npm install
npm run build
Open your docker-compose.yml
file and add a volume to mount your extensions folder into the Docker container:
volumes:
- ./extensions:/directus/extensions/
docker compose up
Usage: npx directus extension:searchsync <subcommand>
Subcommands:
index
- Reindex all documents from the configuration.
The extension uses cosmiconfig for configuration loading with a searchsync
block, or if EXTENSION_SEARCHSYNC_CONFIG_PATH
is set, it will use the specified file.
Configuration can come from one of the following files:
package.json
"searchsync": {...}
.searchsyncrc
.searchsyncrc.json
.searchsyncrc.yaml
.searchsyncrc.yml
.searchsyncrc.js
.searchsyncrc.cjs
searchsync.config.js
searchsync.config.cjs
server: object
- Holds configuration for the search engine.batchLimit: number
- Batch limit when performing index/reindex (defaults to 100).reindexOnStart: boolean
- Performs a full reindex of all documents upon Directus startup.collections: object
- Indexing data definition.collections.<collection>.filter: object
- The filter query in the Directus format to determine which items must be indexed (see Filter Rules).collections.<collection>.fields: array<string>
- Fields that will be indexed in Directus format.collections.<collection>.transform: function
- A callback to return transformed/formatted data for indexing (can only be defined if the config file is.js
).collections.<collection>.indexName: string
- Override collection name when storing in the search index.collections.<collection>.collectionField: string
- If set, adds a field with the collection name value to the indexed document. Useful in conjunction with theindexName
option.
{
"server": {
"type": "meilisearch",
"host": "http://search:7700/myindex",
"key": "the-private-key"
},
"batchLimit": 100,
"reindexOnStart": false,
"collections": {
"products": {
"filter": {
"status": "published",
"stock": "inStock"
},
"fields": [
"title",
"image.id",
"category.title",
"brand.title",
"tags",
"description",
"price",
"rating"
]
},
"posts": {
"indexName": "blog_posts",
"collectionField": "_collection",
"filter": {
"status": "published"
},
"fields": ["title", "teaser", "body", "thumbnail.id"]
}
}
}
const config = {
server: {
type: "meilisearch",
host: "http://search:7700",
key: "the-private-key",
},
reindexOnStart: false,
batchLimit: 100,
collections: {
pages: {
filter: {
status: "published",
},
fields: ["title", "teaser", "body", "thumbnail.id"],
transform: (item, { flattenObject, striptags }) => ({
...flattenObject(item),
body: striptags(item.body),
someCustomValue: "Hello World!",
}),
},
},
};
module.exports = config;
/**
* @param {Object} item
* @param {{striptags, flattenObject, objectMap}} utils
* @param {String} collectionName
* @returns {Object}
*/
function (item, { striptags, flattenObject, objectMap }, collectionName) {
return item;
}
{
"type": "meilisearch",
"host": "http://search:7700",
"key": "the-private-key"
}
{
"type": "algolia",
"appId": "Application-Id",
"key": "secret-api-key"
}
New typeless behavior, use collection names as the index name.
{
"type": "elasticsearch",
"host": "http://search:9200/"
}
With authentication:
{
"type": "elasticsearch",
"host": "http://search:9200/",
"username": "elastic",
"password": "somepassword"
}
Ignore SSL certificate error:
{
"type": "elasticsearch",
"host": "http://search:9200/",
"ignore_cert": true
}
Old type behavior, use collection names as types.
{
"type": "elasticsearch_legacy",
"host": "http://search:9200/projectindex"
}