This guide will help you get started with feathers-elasticsearch, a Feathers database adapter for Elasticsearch.
npm install feathers-elasticsearch @elastic/elasticsearch --save- Feathers v5 (Dove)
- Elasticsearch 8.x and 9.x
- Node.js 18+
Important:
feathers-elasticsearchimplements the Feathers Common database adapter API and querying syntax.
feathers-elasticsearch is currently tested on Elasticsearch 5.0, 5.6, 6.6, 6.7, 6.8, 7.0, 7.1, 8.x, and 9.x.
Note: We have recently dropped support for version 2.4, as its life ended quite a while back. If you are still running Elasticsearch 2.4 and want to take advantage of feathers-elasticsearch, please use version 2.x of this package.
The following bare-bones example will create a messages endpoint and connect to a local messages type in the test index in your Elasticsearch database:
const feathers = require('@feathersjs/feathers');
const elasticsearch = require('@elastic/elasticsearch');
const service = require('feathers-elasticsearch');
const app = feathers();
app.use('/messages', service({
Model: new elasticsearch.Client({
node: 'http://localhost:9200'
}),
elasticsearch: {
index: 'test',
type: 'messages'
}
}));Here's a complete example of a Feathers server with REST API using feathers-elasticsearch:
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const service = require('feathers-elasticsearch');
const elasticsearch = require('@elastic/elasticsearch');
// Create the Elasticsearch client
const esClient = new elasticsearch.Client({
node: 'http://localhost:9200'
});
// Create the message service
const messageService = service({
Model: esClient,
paginate: {
default: 10,
max: 50
},
elasticsearch: {
index: 'test',
type: 'messages',
refresh: true // Make changes immediately visible (not recommended for production)
},
esVersion: '8.0'
});
// Initialize the application
const app = express(feathers());
// Enable JSON parsing
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Enable REST services
app.configure(express.rest());
// Register the message service
app.use('/messages', messageService);
// Enable error handling
app.use(express.errorHandler());
// Start the server
app.listen(3030);
console.log('Feathers app started on http://127.0.0.1:3030');You can run this example and test it:
- Start your Elasticsearch server (ensure it's running on
localhost:9200) - Run the example code above
- Visit http://localhost:3030/messages
You should see an empty array []. That's because you don't have any messages yet, but you now have full CRUD for your new message service!
Using curl:
curl -X POST http://localhost:3030/messages \
-H "Content-Type: application/json" \
-d '{"text": "Hello Feathers!"}'Or using JavaScript:
// Using the Feathers client
const message = await app.service('messages').create({
text: 'Hello Feathers!'
});
console.log(message);// Find all messages
const messages = await app.service('messages').find();
// Find with query
const results = await app.service('messages').find({
query: {
text: 'Hello'
}
});
// Find with pagination
const page = await app.service('messages').find({
query: {
$limit: 10,
$skip: 20
}
});Now that you have a basic setup working, you can:
- Configure your service - See Configuration for all available options
- Learn about queries - See Querying for Elasticsearch-specific query syntax
- Optimize performance - See Performance Features
- Secure your service - See Security for security best practices
- Work with relationships - See Parent-Child Relationships
app.use('/messages', service({
Model: esClient,
elasticsearch: { index: 'test', type: 'messages' },
paginate: {
default: 10, // Return 10 items by default
max: 100 // Allow up to 100 items per request
}
}));app.use('/messages', service({
Model: esClient,
elasticsearch: { index: 'test', type: 'messages' },
security: {
maxQueryDepth: 50,
maxBulkOperations: 10000,
allowedRawMethods: [] // Disable raw() method for security
}
}));app.use('/messages', service({
Model: esClient,
elasticsearch: {
index: 'test',
type: 'messages',
refresh: false // Don't wait for refresh (better performance)
// refresh: true // Wait for refresh (immediate visibility)
// refresh: 'wait_for' // Wait for refresh to complete
}
}));See the Configuration Guide for all available options and detailed explanations.