npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@geeky-biz/strapi-plugin-elasticsearch

v0.0.8

Published

A Strapi plugin to enable using Elasticsearch with Strapi CMS.

Downloads

190

Readme

Strapi plugin strapi-plugin-elasticsearch

A plugin to enable integrating Elasticsearch with Strapi CMS.

Installation

via npm:

npm i @geeky-biz/strapi-plugin-elasticsearch

via yarn:

yarn add @geeky-biz/strapi-plugin-elasticsearch

Plugin Configuration

Within your Strapi project's config/plugin.js, enable the plugin and provide the configuration details:

module.exports = {
    // ...
    'elasticsearch': {
      enabled: true,
      config: {
        indexingCronSchedule: "<cron schedule>",
        searchConnector: {
          host: "<hostname for Elasticsearch>",
          username: "<username for Elasticsearch>",
          password: "<password for Elasticsearch>",
          certificate: "<path to the certificate required to connect to Elasticsearch>"
        },
        indexAliasName: "<Alias name for the Elasticsearch index>"
      }  
    },
    // ...
  }

Example plugin configuration (with adequate .env variables set up):

module.exports = {
    // ...
    'elasticsearch': {
      enabled: true,
      config: {
        indexingCronSchedule: "00 23 * * *", //run daily at 11:00 PM
        searchConnector: {
          host: process.env.ELASTIC_HOST,
          username: process.env.ELASTIC_USERNAME,
          password: process.env.ELASTIC_PASSWORD,
          certificate: path.join(__dirname, process.env.ELASTIC_CERT_NAME)
        },
        indexAliasName: process.env.ELASTIC_ALIAS_NAME
      }  
    },
    // ...
  }

Ensuring connection to Elasticsearch

When connected to Elasticsearch, the Connected field within the Setup Information screen shall display true.

image

Configuring collections & attributes to be indexed

The Configure Collections view displays the collections and the fields setup to be indexed.

image

From this view, individual collection can be selected to modify configuration:

image

Configuring indexing for dynamic zone or component attributes

To enable indexing content for attributes of type component or dynamiczone, additional information needs to be provided via JSON in the following format:

{
  "subfields": [
        {
          "component": "<component name within schema.json>",
          "field": "<field name from within that component>"
        },
        {...},
        {...}
      ]
}

Example 1:

If we have an attribute called seo_details of type component like the following within our collection schema.json:

    "seo_details": {
      "type": "component",
      "repeatable": false,
      "component": "metainfo.seo"
    },

And, if we seek to index the contents of the meta_description field belonging to the component seo, our subfields configuration should be:

{
  "subfields": [
        {
          "component": "metainfo.seo",
          "field": "meta_description"
        }
      ]
}

image

Example 2:

If we have an attribute called sections of type dynamiczone within our collection schema.json:

    "sections": {
      "type": "dynamiczone",
      "components": [
        "content.footer",
        "content.paragraph",
        "content.separator",
        "content.heading"
      ]
    },
...

And, if we seek to index the contents of the fields title for content.heading and details as well as subtext for content.paragraph, our subfields configuration should be:

{
  "subfields": [
        {
          "component": "content.paragraph",
          "field": "details"
        },
        {
          "component": "content.paragraph",
          "field": "subtext"
        },
        {
          "component": "content.heading",
          "field": "title"
        }
      ]
}

The subfields JSON also supports multiple level of nesting:

{
  "subfields": [
        {
          "component": "content.footer",
          "field": "footer_link",
          "subfields": [
            {
              "component": "content.link",
              "field": "display_text"
            }
          ]
        }
      ]
}

Note: Indexing of relations attributes isn't yet supported.

Exporting and Importing indexing configuration

To enable backing up the indexing configuration or transferring it between various environments, these can be Exported / Imported from the Configure Collections view.

image

Scheduling Indexing

Once the collection attributes are configured for indexing, any changes to the respective collections & attributes is marked for indexing. The cron job (configured via indexingCronSchedule) makes actual indexing requests to the connected Elasticsearch instance.

  • Trigger Indexing triggers the cron job immediately to perform the pending indexing tasks without waiting for the next scheduled run.
  • Rebuild Indexing completely rebuilds the index. It may be used if the Elasticsearch appears to be out of sync from the data within Strapi.

image

Whenever a collection is configured for indexing, it may already have data that needs to be indexed. To facilitate indexing of the past data, a collection can be scheduled for indexing in the next cron run from the Configure Collections view:

image

Searching

You may directly use the Elasticsearch search API or you may use the Search API exposed by the plugin (at /api/elasticsearch/search). The plugin search API is just a wrapper around the Elasticsearch search API that passes the query parameter to the Elasticsearch search API and returns the results coming from Elasticsearch:

For example, the below API call would result into the Elasticsearch search API being triggered with the query

`/api/elasticsearch/search?query=query%5Bbool%5D%5Bshould%5D%5B0%5D%5Bmatch%5D%5Bcity%5D=atlanta`

would result into the Elasticsearch search API being triggered with query

query[bool][should][0][match][city]=atlanta

The plugin's API would return the response from the Elasticsearch search API.

Note: To use the search API (at /api/elasticsearch/search), you will have to provide access via Settings -> Users & Permissions Plugin -> Roles -> (Select adequate role) -> Elasticsearch -> search.

Extending Search API

The recommended was to enhance the Search API is to write your own route and controller. Below is an example of how this can be achieved (this example adds pagination capability to the search API):

  • Within your setup, create src/extensions/elasticsearch/strapi-server.js with the following contents:
const { Client } = require('@elastic/elasticsearch')
const qs = require('qs');

let client = null;

module.exports = (plugin) => {

    client = new Client({
        node: plugin.config.searchConnector.host,
        auth: {
          username: plugin.config.searchConnector.username,
          password: plugin.config.searchConnector.password
        },
        tls: {
          ca: plugin.config.searchConnector.certificate,
          rejectUnauthorized: false
        }
    });

    plugin.controllers['performSearch'].enhancedSearch = async (ctx) => {
            try
            {
                const params = qs.parse(ctx.request.query)
                const query = params.search;
                const pagesize = params.pagesize;
                const from = params.from;
                const result= await client.search({
                    index: plugin.config.indexAliasName,
                    query: { "bool" : { "should" : [ { "match": { "content": "dummy"} } ] } },
                    size: pagesize,
                    from: from 
                });
                return result;
            }
            catch(err)
            {
                console.log('Search : elasticClient.enhancedSearch : Error encountered while making a search request to ElasticSearch.')
                throw err;
            }
    }

    plugin.routes['search'].routes.push({
        method: 'GET',
        path: '/enhanced-search',
        handler: 'performSearch.enhancedSearch',
      });
  
    
    return plugin;
};
  • This will create a new route /api/elasticsearch/enhanced-search being served by the function defined above.
  • You can add / modify the routes and controllers as necessary.

Bugs

For any bugs, please create an issue here.

About

  • This plugin is created by Punit Sethi.
  • I'm an independent developer working on Strapi migrations, customizations, configuration projects (see here).
  • For any Strapi implementation requirement, write to me at [email protected].