🗄️ Database
Elasticsearch Search Engine
Last updated: 2025-09-25 02:29:54
Elasticsearch Full-Text Search
Elasticsearch is a distributed search and analytics engine built on Apache Lucene.
Basic Elasticsearch Operations
// Node.js client setup
const { Client } = require('@elastic/elasticsearch');
const client = new Client({
node: 'http://localhost:9200',
auth: {
username: 'elastic',
password: 'password'
}
});
// Create an index
async function createIndex(indexName) {
try {
await client.indices.create({
index: indexName,
body: {
mappings: {
properties: {
title: {
type: 'text',
analyzer: 'standard'
},
content: {
type: 'text',
analyzer: 'standard'
},
author: {
type: 'keyword'
},
publishDate: {
type: 'date'
},
tags: {
type: 'keyword'
},
category: {
type: 'keyword'
}
}
}
}
});
} catch (error) {
console.error('Error creating index:', error);
}
}
// Index a document
async function indexDocument(indexName, document) {
try {
const response = await client.index({
index: indexName,
body: document
});
return response.body._id;
} catch (error) {
console.error('Error indexing document:', error);
}
}
Search Queries
// Basic search
async function basicSearch(indexName, query) {
try {
const response = await client.search({
index: indexName,
body: {
query: {
match: {
title: query
}
}
}
});
return response.body.hits;
} catch (error) {
console.error('Error searching:', error);
}
}
// Advanced search with filters
async function advancedSearch(indexName, searchParams) {
const {
query,
category,
author,
dateFrom,
dateTo,
tags,
size = 10,
from = 0
} = searchParams;
const searchBody = {
query: {
bool: {
must: [],
filter: []
}
},
sort: [
{ publishDate: { order: 'desc' } },
'_score'
],
size,
from
};
// Add text search
if (query) {
searchBody.query.bool.must.push({
multi_match: {
query,
fields: ['title^2', 'content'],
type: 'best_fields',
fuzziness: 'AUTO'
}
});
}
// Add filters
if (category) {
searchBody.query.bool.filter.push({
term: { category }
});
}
if (author) {
searchBody.query.bool.filter.push({
term: { author }
});
}
if (dateFrom || dateTo) {
const dateRange = {};
if (dateFrom) dateRange.gte = dateFrom;
if (dateTo) dateRange.lte = dateTo;
searchBody.query.bool.filter.push({
range: { publishDate: dateRange }
});
}
if (tags && tags.length > 0) {
searchBody.query.bool.filter.push({
terms: { tags }
});
}
try {
const response = await client.search({
index: indexName,
body: searchBody
});
return response.body;
} catch (error) {
console.error('Error in advanced search:', error);
}
}
Aggregations and Analytics
// Aggregations for analytics
async function getAnalytics(indexName) {
try {
const response = await client.search({
index: indexName,
body: {
size: 0, // Don't return documents, just aggregations
aggs: {
categories: {
terms: {
field: 'category',
size: 10
}
},
authors: {
terms: {
field: 'author',
size: 10
}
},
posts_over_time: {
date_histogram: {
field: 'publishDate',
calendar_interval: 'month'
}
},
popular_tags: {
terms: {
field: 'tags',
size: 20
}
},
avg_posts_per_author: {
avg: {
script: {
source: '1' // Each document represents one post
}
}
}
}
}
});
return response.body.aggregations;
} catch (error) {
console.error('Error getting analytics:', error);
}
}
// Search suggestions
async function getSearchSuggestions(indexName, prefix) {
try {
const response = await client.search({
index: indexName,
body: {
suggest: {
title_suggest: {
prefix,
completion: {
field: 'title_suggest',
size: 5
}
}
}
}
});
return response.body.suggest.title_suggest[0].options;
} catch (error) {
console.error('Error getting suggestions:', error);
}
}
Bulk Operations
// Bulk indexing
async function bulkIndex(indexName, documents) {
const body = [];
documents.forEach(doc => {
body.push({
index: {
_index: indexName,
_id: doc.id
}
});
body.push(doc);
});
try {
const response = await client.bulk({
refresh: true,
body
});
if (response.body.errors) {
console.error('Bulk indexing errors:', response.body.items);
}
return response.body;
} catch (error) {
console.error('Bulk indexing error:', error);
}
}
// Update documents
async function updateDocument(indexName, documentId, updates) {
try {
const response = await client.update({
index: indexName,
id: documentId,
body: {
doc: updates,
doc_as_upsert: true
}
});
return response.body;
} catch (error) {
console.error('Error updating document:', error);
}
}
// Delete documents by query
async function deleteByQuery(indexName, query) {
try {
const response = await client.deleteByQuery({
index: indexName,
body: {
query
}
});
return response.body;
} catch (error) {
console.error('Error deleting documents:', error);
}
}