Quick start guide

Install and start Manticore

You can install and start Manticore easily in Ubuntu, Centos, Debian, Windows and MacOS or use Manticore as a docker container.

  • Ubuntu
  • Debian
  • Centos
  • Windows
  • MacOS
  • Docker

Ubuntu Debian Centos Windows MacOS Docker

  1. wget https://repo.manticoresearch.com/manticore-repo.noarch.deb
  2. sudo dpkg -i manticore-repo.noarch.deb
  3. sudo apt update
  4. sudo apt install manticore manticore-columnar-lib
  5. sudo systemctl start manticore
  1. wget https://repo.manticoresearch.com/manticore-repo.noarch.deb
  2. sudo dpkg -i manticore-repo.noarch.deb
  3. sudo apt update
  4. sudo apt install manticore manticore-columnar-lib
  5. sudo systemctl start manticore
  1. sudo yum install https://repo.manticoresearch.com/manticore-repo.noarch.rpm
  2. sudo yum install manticore manticore-columnar-lib
  3. sudo systemctl start manticore
  • Download Windows archive from https://manticoresearch.com/install/
  • Extract all from the archive to C:\Manticore
    1. C:\Manticore\bin\searchd --install --config C:\Manticore\sphinx.conf.in --servicename Manticore
  • Start Manticore from the Services snap-in of the Microsoft Management Console

  1. brew install manticoresearch
  2. brew services start manticoresearch
  1. docker pull manticoresearch/manticore
  2. docker run -e EXTRA=1 --name manticore -p9306:9306 -p9308:9308 -p9312:9312 -d manticoresearch/manticore

For persisting your data directory read how to use Manticore docker in production

Connect to Manticore

By default Manticore is waiting for your connections on:

  • port 9306 for MySQL clients
  • port 9308 for HTTP/HTTPS connections
  • port 9312 for connections from other Manticore nodes and clients based on Manticore binary API
  • SQL
  • HTTP
  • PHP
  • Python
  • Javascript
  • Java

SQL HTTP PHP Python Javascript Java

  1. mysql -h0 -P9306

HTTP is a stateless protocol so it doesn’t require any special connection phase:

  1. curl -s "http://localhost:9308/search"
  1. // https://github.com/manticoresoftware/manticoresearch-php
  2. require_once __DIR__ . '/vendor/autoload.php';
  3. $config = ['host'=>'127.0.0.1','port'=>9308];
  4. $client = new \Manticoresearch\Client($config);
  1. // https://github.com/manticoresoftware/manticoresearch-python
  2. import manticoresearch
  3. config = manticoresearch.Configuration(
  4. host = "http://127.0.0.1:9308"
  5. )
  6. client = manticoresearch.ApiClient(config)
  7. indexApi = manticoresearch.IndexApi(client)
  8. searchApi = manticoresearch.SearchApi(client)
  9. utilsApi = manticoresearch.UtilsApi(client)
  1. // https://github.com/manticoresoftware/manticoresearch-javascript
  2. var Manticoresearch = require('manticoresearch');
  3. var client= new Manticoresearch.ApiClient()
  4. client.basePath="http://127.0.0.1:9308";
  5. indexApi = new Manticoresearch.IndexApi(client);
  6. searchApi = new Manticoresearch.SearchApi(client);
  7. utilsApi = new Manticoresearch.UtilsApi(client);
  1. // https://github.com/manticoresoftware/manticoresearch-java
  2. import com.manticoresearch.client.*;
  3. import com.manticoresearch.client.model.*;
  4. import com.manticoresearch.client.api.*;
  5. ...
  6. ApiClient client = Configuration.getDefaultApiClient();
  7. client.setBasePath("http://127.0.0.1:9308");
  8. ...
  9. IndexApi indexApi = new IndexApi(client);
  10. SearchApi searchApi = new UtilsApi(client);
  11. UtilsApi utilsApi = new UtilsApi(client);

Create a table

Let’s now create a table called “products” with 2 fields:

  • title - full-text field which will contain our product’s title
  • price - of type “float”

Note that it is possible to omit creating a table with an explicit create statement. For more information, see Auto schema.

  • SQL
  • HTTP
  • PHP
  • Python
  • Javascript
  • Java

SQL HTTP PHP Python Javascript Java

  1. create table products(title text, price float) morphology='stem_en';
  1. POST /cli -d "create table products(title text, price float) morphology='stem_en'"
  1. $index = new \Manticoresearch\Index($client);
  2. $index->setName('products');
  3. $index->create([
  4. 'title'=>['type'=>'text'],
  5. 'price'=>['type'=>'float'],
  6. ],['morphology' => 'stem_en']);
  1. utilsApi.sql('create table products(title text, price float) morphology=\'stem_en\'')
  1. res = await utilsApi.sql('create table products(title text, price float) morphology=\'stem_en\'');
  1. utilsApi.sql("create table products(title text, price float) morphology='stem_en'");

Response

  1. Query OK, 0 rows affected (0.02 sec)
  1. {
  2. "total":0,
  3. "error":"",
  4. "warning":""
  5. }

Add documents

Let’s now add few documents to the table:

  • SQL
  • JSON
  • PHP
  • Python
  • Javascript
  • Java

SQL JSON PHP Python Javascript Java

  1. insert into products(title,price) values ('Crossbody Bag with Tassel', 19.85), ('microfiber sheet set', 19.99), ('Pet Hair Remover Glove', 7.99);

"id":0 or no id forces automatic ID generation.

  1. POST /insert
  2. {
  3. "index":"products",
  4. "doc":
  5. {
  6. "title" : "Crossbody Bag with Tassel",
  7. "price" : 19.85
  8. }
  9. }
  10. POST /insert
  11. {
  12. "index":"products",
  13. "doc":
  14. {
  15. "title" : "microfiber sheet set",
  16. "price" : 19.99
  17. }
  18. }
  19. POST /insert
  20. {
  21. "index":"products",
  22. "doc":
  23. {
  24. "title" : "Pet Hair Remover Glove",
  25. "price" : 7.99
  26. }
  27. }
  1. $index->addDocuments([
  2. ['title' => 'Crossbody Bag with Tassel', 'price' => 19.85],
  3. ['title' => 'microfiber sheet set', 'price' => 19.99],
  4. ['title' => 'Pet Hair Remover Glove', 'price' => 7.99]
  5. ]);
  1. indexApi.insert({"index" : "test", "doc" : {"title" : "Crossbody Bag with Tassel", "price" : 19.85}})
  2. indexApi.insert({"index" : "test", "doc" : {"title" : "microfiber sheet set", "price" : 19.99}})
  3. indexApi.insert({"index" : "test", "doc" : {"title" : "Pet Hair Remover Glove", "price" : 7.99}})
  1. res = await indexApi.insert({"index" : "test", "doc" : {"title" : "Crossbody Bag with Tassel", "price" : 19.85}});
  2. res = await indexApi.insert({"index" : "test", "doc" : {"title" : "microfiber sheet set", "price" : 19.99}});
  3. res = await indexApi.insert({"index" : "test", doc" : {"title" : "Pet Hair Remover Glove", "price" : 7.99}});
  1. InsertDocumentRequest newdoc = new InsertDocumentRequest();
  2. HashMap<String,Object> doc = new HashMap<String,Object>(){{
  3. put("title","Crossbody Bag with Tassel");
  4. put("price",19.85);
  5. }};
  6. newdoc.index("products").setDoc(doc);
  7. sqlresult = indexApi.insert(newdoc);
  8. newdoc = new InsertDocumentRequest();
  9. doc = new HashMap<String,Object>(){{
  10. put("title","microfiber sheet set");
  11. put("price",19.99);
  12. }};
  13. newdoc.index("products").setDoc(doc);
  14. sqlresult = indexApi.insert(newdoc);
  15. newdoc = new InsertDocumentRequest();
  16. doc = new HashMap<String,Object>(){{
  17. put("title","Pet Hair Remover Glove");
  18. put("price",7.99);
  19. }};
  20. newdoc.index("products").setDoc(doc);
  21. indexApi.insert(newdoc);

Response

  1. Query OK, 3 rows affected (0.01 sec)
  1. {
  2. "_index": "products",
  3. "_id": 0,
  4. "created": true,
  5. "result": "created",
  6. "status": 201
  7. }
  8. {
  9. "_index": "products",
  10. "_id": 0,
  11. "created": true,
  12. "result": "created",
  13. "status": 201
  14. }
  15. {
  16. "_index": "products",
  17. "_id": 0,
  18. "created": true,
  19. "result": "created",
  20. "status": 201
  21. }

Let’s find one of the documents. The query we will use is ‘remove hair’. As you can see it finds document with title ‘Pet Hair Remover Glove’ and highlights ‘Hair remover’ in it even though the query has “remove”, not “remover”. This is because when we created the table we turned on using English stemming (morphology "stem_en").

  • SQL
  • JSON
  • PHP
  • Python
  • javascript
  • Java

SQL JSON PHP Python javascript Java

  1. select id, highlight(), price from products where match('remove hair');
  1. POST /search
  2. {
  3. "index": "products",
  4. "query": { "match": { "title": "remove hair" } },
  5. "highlight":
  6. {
  7. "fields": ["title"]
  8. }
  9. }
  1. $result = $index->search('@title remove hair')->highlight(['title'])->get();
  2. foreach($result as $doc)
  3. {
  4. echo "Doc ID: ".$doc->getId()."\n";
  5. echo "Doc Score: ".$doc->getScore()."\n";
  6. echo "Document fields:\n";
  7. print_r($doc->getData());
  8. echo "Highlights: \n";
  9. print_r($doc->getHighlight());
  10. }
  1. searchApi.search({"index":"myindex","query":{"query_string":"@title remove hair"},"highlight":{"fields":["title"]}})
  1. res = await searchApi.search({"index":"myindex","query":{"query_string":"@title remove hair"}"highlight":{"fields":["title"]}});
  1. query = new HashMap<String,Object>();
  2. query.put("query_string","@title remove hair");
  3. searchRequest = new SearchRequest();
  4. searchRequest.setIndex("forum");
  5. searchRequest.setQuery(query);
  6. HashMap<String,Object> highlight = new HashMap<String,Object>(){{
  7. put("fields",new String[] {"title"});
  8. }};
  9. searchRequest.setHighlight(highlight);
  10. searchResponse = searchApi.search(searchRequest);

Response

  1. +---------------------+-------------------------------+----------+
  2. | id | highlight() | price |
  3. +---------------------+-------------------------------+----------+
  4. | 1513686608316989452 | Pet <strong>Hair Remover</strong> Glove | 7.990000 |
  5. +---------------------+-------------------------------+----------+
  6. 1 row in set (0.00 sec)
  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "hits": {
  5. "total": 1,
  6. "hits": [
  7. {
  8. "_id": "1513686608316989452",
  9. "_score": 1680,
  10. "_source": {
  11. "price": 7.99,
  12. "title": "Pet Hair Remover Glove"
  13. },
  14. "highlight": {
  15. "title": [
  16. "Pet <strong>Hair Remover</strong> Glove"
  17. ]
  18. }
  19. }
  20. ]
  21. }
  22. }
  1. Doc ID: 1513686608316989452
  2. Doc Score: 1680
  3. Document fields:
  4. Array
  5. (
  6. [price] => 7.99
  7. [title] => Pet Hair Remover Glove
  8. )
  9. Highlights:
  10. Array
  11. (
  12. [title] => Array
  13. (
  14. [0] => Pet <strong>Hair Remover</strong> Glove
  15. )
  16. )

`

  1. {'hits': {'hits': [{u'_id': u'1513686608316989452',
  2. u'_score': 1680,
  3. u'_source': {u'title': u'Pet Hair Remover Glove', u'price':7.99},
  4. u'highlight':{u'title':[u'Pet <strong>Hair Remover</strong> Glove']}}}],
  5. 'total': 1},
  6. 'profile': None,
  7. 'timed_out': False,
  8. 'took': 0}
  1. {"hits": {"hits": [{"_id": "1513686608316989452",
  2. "_score": 1680,
  3. "_source": {"title": "Pet Hair Remover Glove", "price":7.99},
  4. "highlight":{"title":["Pet <strong>Hair Remover</strong> Glove"]}}],
  5. "total": 1},
  6. "profile": None,
  7. "timed_out": False,
  8. "took": 0}
  1. class SearchResponse {
  2. took: 84
  3. timedOut: false
  4. hits: class SearchResponseHits {
  5. total: 1
  6. maxScore: null
  7. hits: [{_id=1513686608316989452, _score=1, _source={price=7.99, title=Pet Hair Remover Glove}, highlight={title=[Pet <strong>Hair Remover</strong> Glove]}}]
  8. aggregations: null
  9. }
  10. profile: null
  11. }

Update

Let’s assume we now want to update the document - change the price to 18.5. This can be done by filtering by any field, but normally you know the document id and update something based on that.

  • SQL
  • JSON
  • PHP
  • Python
  • javascript
  • Java

SQL JSON PHP Python javascript Java

  1. update products set price=18.5 where id = 1513686608316989452;
  1. POST /update
  2. {
  3. "index": "products",
  4. "id": 1513686608316989452,
  5. "doc":
  6. {
  7. "price": 18.5
  8. }
  9. }
  1. $doc = [
  2. 'body' => [
  3. 'index' => 'products',
  4. 'id' => 2,
  5. 'doc' => [
  6. 'price' => 18.5
  7. ]
  8. ]
  9. ];
  10. $response = $client->update($doc);
  1. indexApi = api = manticoresearch.IndexApi(client)
  2. indexApi.update({"index" : "products", "id" : 1513686608316989452, "doc" : {"price":18.5}})
  1. res = await indexApi.update({"index" : "products", "id" : 1513686608316989452, "doc" : {"price":18.5}});
  1. UpdateDocumentRequest updateRequest = new UpdateDocumentRequest();
  2. doc = new HashMap<String,Object >(){{
  3. put("price",18.5);
  4. }};
  5. updateRequest.index("products").id(1513686608316989452L).setDoc(doc);
  6. indexApi.update(updateRequest);

Response

  1. Query OK, 1 row affected (0.00 sec)
  1. {
  2. "_index": "products",
  3. "_id": 1513686608316989452,
  4. "result": "updated"
  5. }

Delete

Let’s now delete all documents with price lower than 10.

  • SQL
  • JSON
  • PHP
  • Python
  • javascript
  • Java

SQL JSON PHP Python javascript Java

  1. delete from products where price < 10;
  1. POST /delete
  2. {
  3. "index": "products",
  4. "query":
  5. {
  6. "range":
  7. {
  8. "price":
  9. {
  10. "lte": 10
  11. }
  12. }
  13. }
  14. }
  1. $result = $index->deleteDocuments(new \Manticoresearch\Query\Range('price',['lte'=>10]));
  1. indexApi.delete({"index" : "products", "query": {"range":{"price":{"lte":10}}}})
  1. res = await indexApi.delete({"index" : "products", "query": {"range":{"price":{"lte":10}}}});
  1. DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
  2. query = new HashMap<String,Object>();
  3. query.put("range",new HashMap<String,Object>(){{
  4. put("range",new HashMap<String,Object>(){{
  5. put("lte",10);
  6. }});
  7. }});
  8. deleteRequest.index("products").setQuery(query);
  9. indexApi.delete(deleteRequest);

Response

  1. Query OK, 1 row affected (0.00 sec)
  1. {
  2. "_index": "products",
  3. "deleted": 1
  4. }
  1. Array
  2. (
  3. [_index] => products
  4. [deleted] => 1
  5. )

Starting the server

Manticore Search server can be started in several ways, depending on how it was installed.

Starting Manticore in Linux

When Manticore Search is installed using DEB or RPM packages, the searchd process can be run and managed by operating system’s init system. Most Linux versions now use systemd, while older releases use SysV init.

If you are not sure about the type of the init system your platform use, run:

  1. ps --no-headers -o comm 1

Starting and stopping using systemd

After the installation the Manticore Search service is not started automatically. To start Manticore run the following command:

  1. sudo systemctl start manticore

To stop Manticore run the following command:

  1. sudo systemctl stop manticore

The Manticore service is set to run at boot. You can check it by running:

  1. sudo systemctl is-enabled manticore

If you want to disable Manticore starting at boot time run:

  1. sudo systemctl disable manticore

To make Manticore start at boot, run:

  1. sudo systemctl enable manticore

In some newer operating systems it can fail with error “Failed to enable unit: Unit … is transient or generated.”. In this case you can remove the generator and try again. It’s unlikely you need the generator ever again after Manticore is installed.

In Debian-based operating systems run:

  1. sudo rm /lib/systemd/system-generators/manticore-generator
  2. sudo systemctl daemon-reload

In CentOS and RHEL run:

  1. sudo rm /usr/lib/systemd/system-generators/manticore-search-generator
  2. sudo systemctl daemon-reload

If you still need the generator again just install the Manticore packages again and it will recover the generator file.

searchd process logs startup information in systemd journal. If systemd logging is enabled you can view the logged information with the following command:

  1. sudo journalctl --unit manticore

Custom startup flags using systemd

systemctl set-environment _ADDITIONAL_SEARCHD_PARAMS allows you to specify custom startup flags Manticore Search daemon should be started with. See full list here.

For example, to start Manticore with debug logging level you can run:

  1. systemctl set-environment _ADDITIONAL_SEARCHD_PARAMS='--logdebug'
  2. systemctl restart manticore

To undo it run:

  1. systemctl set-environment _ADDITIONAL_SEARCHD_PARAMS=''
  2. systemctl restart manticore

Note, systemd environment variables get reset on server reboot.

Starting and stopping using service

Manticore can be started and stopped using service commands:

  1. sudo service manticore start
  2. sudo service manticore stop

To enable the sysV service at boot on RedHat systems run:

  1. chkconfig manticore on

To enable the sysV service at boot on Debian systems (including Ubuntu) run:

  1. update-rc.d manticore defaults

Please note that searchd is started by the init system under manticore user and all files created by the server will be owned by this user. If searchd is started under ,for example, root user, the permissions of files will be changed which may lead to issues when running again searchd as service.