ManticoreSearch Installation and Configuration
ManticoreSearch is a high-performance full-text search engine with a MySQL-compatible SQL interface and real-time indexing, designed as a modern replacement for Sphinx Search. This guide covers installing ManticoreSearch on Linux, using the SQL interface, creating real-time indexes, integrating data sources, replication, and migrating from Sphinx.
Prerequisites
- Ubuntu 20.04+ / Debian 11+ or CentOS 8+ / Rocky Linux 8+
- 1 GB RAM minimum (more RAM = better performance)
- MySQL client tools for interacting with Manticore
- Root or sudo access
Installing ManticoreSearch
# Ubuntu/Debian
wget https://repo.manticoresearch.com/manticore-repo.noarch.deb
sudo dpkg -i manticore-repo.noarch.deb
sudo apt-get update
sudo apt-get install -y manticore manticore-extra
# CentOS/Rocky Linux
sudo rpm --import https://repo.manticoresearch.com/GPG-KEY-manticore
wget https://repo.manticoresearch.com/manticore-repo.noarch.rpm
sudo rpm -i manticore-repo.noarch.rpm
sudo dnf install -y manticore manticore-extra
# Verify installation
searchd --version
# Enable and start the service
sudo systemctl enable --now manticore
sudo systemctl status manticore
# Connect with MySQL client (Manticore uses MySQL protocol on port 9306)
mysql -h 127.0.0.1 -P 9306 -u root
Once connected you'll see a MySQL-like prompt. Manticore uses standard SQL syntax for search operations.
Configuration Overview
The main configuration file is /etc/manticoresearch/manticore.conf:
# /etc/manticoresearch/manticore.conf
searchd {
listen = 127.0.0.1:9306:mysql41 # MySQL protocol
listen = 127.0.0.1:9308:http # HTTP/JSON API
listen = 127.0.0.1:9312 # Binary protocol (Sphinx compat)
log = /var/log/manticore/searchd.log
query_log = /var/log/manticore/query.log
query_log_format = sphinxql
pid_file = /run/manticore/searchd.pid
data_dir = /var/lib/manticore/data
# Performance
max_children = 30
net_throttle_accept = 0
binlog_path = /var/lib/manticore/binlog
}
Restart after config changes:
sudo systemctl restart manticore
Creating Real-Time Indexes
Real-time (RT) indexes accept INSERT, UPDATE, and DELETE operations immediately without rebuilding:
-- Connect to ManticoreSearch
mysql -h 127.0.0.1 -P 9306
-- Create a real-time index
CREATE TABLE products (
id BIGINT,
title TEXT,
description TEXT,
category STRING,
brand STRING,
price FLOAT,
in_stock BOOL,
tags STRING ATTRIBUTE MULTI,
created_at TIMESTAMP
) engine='columnar';
-- The 'id' column is the primary key (must be a positive integer)
-- TEXT columns are full-text indexed
-- STRING columns are for filtering and sorting (not full-text)
-- ATTRIBUTE MULTI = multi-valued attribute (like an array)
Indexing and Querying with SQL
-- Insert documents
INSERT INTO products (id, title, description, category, brand, price, in_stock, tags)
VALUES
(1, 'Mechanical Keyboard TKL', 'Cherry MX Brown switches tenkeyless layout', 'Electronics', 'Keychron', 89.99, 1, (1,2,3)),
(2, 'Ergonomic Vertical Mouse', 'Reduces wrist strain for long work sessions', 'Electronics', 'Logitech', 45.00, 0, (2,4)),
(3, 'USB-C Hub 7-in-1', 'HDMI, USB-A, SD card, power delivery', 'Electronics', 'Anker', 39.99, 1, (5,6));
-- Full-text search
SELECT id, title, price, WEIGHT() AS relevance
FROM products
WHERE MATCH('mechanical keyboard')
ORDER BY relevance DESC;
-- Full-text with filters
SELECT id, title, brand, price
FROM products
WHERE MATCH('keyboard OR mouse')
AND price < 100
AND in_stock = 1
ORDER BY price ASC
LIMIT 10;
-- Full-text search with field-specific matching
SELECT id, title
FROM products
WHERE MATCH('@title mechanical @description switches');
-- Update a document
UPDATE products SET price = 79.99, in_stock = 1 WHERE id = 2;
-- Delete
DELETE FROM products WHERE id = 3;
-- Truncate (remove all documents)
TRUNCATE RTINDEX products;
Plain Indexes from Data Sources
Plain indexes are built from a data source (MySQL, PostgreSQL, etc.) and are read-only after building. Useful for large static datasets:
# Add to /etc/manticoresearch/manticore.conf
source products_src {
type = mysql
sql_host = localhost
sql_user = myuser
sql_pass = mypassword
sql_db = mydb
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = SELECT id, title, description, category, price, UNIX_TIMESTAMP(created_at) AS created_ts FROM products WHERE id >= $start AND id <= $end
sql_query_range = SELECT MIN(id), MAX(id) FROM products
sql_range_step = 1000
# Declare non-full-text attributes
sql_attr_float = price
sql_attr_string = category
sql_attr_uint = created_ts
}
index products_plain {
type = plain
source = products_src
path = /var/lib/manticore/data/products_plain
}
Build and rotate the index:
# Build the plain index
sudo -u manticore indexer --config /etc/manticoresearch/manticore.conf products_plain
# Rotate (load new index without downtime)
sudo -u manticore indexer --config /etc/manticoresearch/manticore.conf --rotate products_plain
# Or rebuild all indexes
sudo -u manticore indexer --all --rotate
Full-Text Search Features
-- Boolean operators
SELECT * FROM products WHERE MATCH('keyboard AND switches');
SELECT * FROM products WHERE MATCH('keyboard OR mouse');
SELECT * FROM products WHERE MATCH('keyboard NOT gaming');
-- Phrase search
SELECT * FROM products WHERE MATCH('"mechanical keyboard"');
-- Proximity search (words within N positions)
SELECT * FROM products WHERE MATCH('"keyboard switches"~5');
-- Wildcard search (requires min_prefix_len or min_infix_len in config)
SELECT * FROM products WHERE MATCH('key*');
-- Fuzzy / typo-tolerant search
SELECT * FROM products WHERE MATCH('keyborad~1'); -- 1 edit distance
-- Field weighting
SELECT id, title, WEIGHT() AS w
FROM products
WHERE MATCH('keyboard')
OPTION field_weights=(title=10, description=1)
ORDER BY w DESC;
-- Faceted search with grouping
SELECT category, COUNT(*) AS cnt, AVG(price) AS avg_price
FROM products
WHERE MATCH('keyboard')
GROUP BY category
ORDER BY cnt DESC;
-- SNIPPET - highlight matched terms
SELECT id, SNIPPET(description, 'mechanical keyboard', 'limit=200,around=5') AS excerpt
FROM products
WHERE MATCH('mechanical keyboard');
Configure fuzzy and wildcard support in manticore.conf:
index products {
# ...
min_prefix_len = 3 # Enable prefix wildcards (key* matches keyboard)
min_infix_len = 3 # Enable infix wildcards (*board* matches keyboard)
morphology = stem_en # English stemming (run = running = ran)
}
Replication and High Availability
ManticoreSearch supports streaming replication for real-time indexes:
-- On the primary node: create a replication cluster
CREATE CLUSTER my_cluster;
-- Add an index to the cluster
ALTER CLUSTER my_cluster ADD products;
-- On each replica node, join the cluster
-- (replace primary_ip with the actual IP)
JOIN CLUSTER my_cluster AT 'primary_ip:9312';
-- Check cluster status
SHOW STATUS LIKE 'cluster%';
Clients should connect to any node in the cluster. For load balancing, use HAProxy:
# HAProxy frontend for ManticoreSearch
listen manticore
bind 0.0.0.0:9306
mode tcp
balance roundrobin
server node1 192.168.1.10:9306 check
server node2 192.168.1.11:9306 check
server node3 192.168.1.12:9306 check
Troubleshooting
Check logs:
sudo tail -f /var/log/manticore/searchd.log
sudo tail -f /var/log/manticore/query.log
ManticoreSearch won't start:
# Test config file syntax
searchd --config /etc/manticoresearch/manticore.conf --stopwait
searchd --config /etc/manticoresearch/manticore.conf --status
Index not found or empty:
-- List all indexes
SHOW TABLES;
-- Check index status
SHOW INDEX products STATUS;
SHOW INDEX products SETTINGS;
Full-text query returns no results:
-- Check that the index has documents
SELECT COUNT(*) FROM products;
-- Debug MATCH query
SELECT id, title, WEIGHT() FROM products WHERE MATCH('keyboard') OPTION ranker=none;
-- WEIGHT() = 1 means no ranking, confirms documents are found
Slow queries:
-- Check query log for slow queries
-- Set in config:
-- query_log_min_msec = 100 (log queries over 100ms)
-- Check index statistics
CALL KEYWORDS('mechanical keyboard', 'products', 1);
-- Shows term frequency and statistics
Migrate from Sphinx:
# ManticoreSearch is API-compatible with Sphinx 2.x
# Most Sphinx configs work with minimal changes:
# 1. Replace 'sphinx' with 'manticore' in service names
# 2. Update the data_dir path
# 3. Change listen syntax if needed
# Existing plain indexes can be used directly by copying files
Conclusion
ManticoreSearch delivers exceptional full-text search performance with a familiar SQL interface, making it accessible to developers who know MySQL. Real-time indexes provide instant write visibility, while plain indexes built from SQL databases handle large static datasets efficiently. The built-in streaming replication enables high availability without external tools, and the Sphinx compatibility layer simplifies migration for existing deployments. For production use, configure replication across at least two nodes and use HAProxy or a similar load balancer for connection distribution.


