Вы можете легко установить и запустить Manticore на различных операционных системах, включая Ubuntu, Centos, Debian, Windows и MacOS. Кроме того, вы также можете использовать Manticore в виде Docker-контейнера.
- Ubuntu
- Debian
- Centos
- Windows
- MacOS
- Docker
wget https://repo.manticoresearch.com/manticore-repo.noarch.deb
sudo dpkg -i manticore-repo.noarch.deb
sudo apt update
sudo apt install manticore manticore-columnar-lib
sudo systemctl start manticorewget https://repo.manticoresearch.com/manticore-repo.noarch.deb
sudo dpkg -i manticore-repo.noarch.deb
sudo apt update
sudo apt install manticore manticore-columnar-lib
sudo systemctl start manticoresudo yum install https://repo.manticoresearch.com/manticore-repo.noarch.rpm
sudo yum install manticore manticore-columnar-lib
sudo systemctl start manticore- Скачайте архив для Windows с https://manticoresearch.com/install/
- Распакуйте все файлы из архива в
C:\Manticore - Выполните следующую команду для установки Manticore как службы:
-
C:\Manticore\bin\searchd --install --config C:\Manticore\sphinx.conf.in --servicename Manticore - Запустите Manticore через оснастку служб Microsoft Management Console.
brew install manticoresearch
brew services start manticoresearchdocker pull manticoresearch/manticore
docker run --name manticore -p9306:9306 -p9308:9308 -p9312:9312 -d manticoresearch/manticoreДля сохранения данных вашего каталога, прочитайте как использовать Manticore docker в продакшене
По умолчанию Manticore ожидает подключения на:
- порт 9306 для клиентов MySQL
- порт 9308 для HTTP/HTTPS соединений
- порт 9312 для соединений с другими узлами Manticore и клиентами, использующими бинарный API Manticore
Более подробную информацию о поддержке HTTPS можно найти в нашем обучающем курсе здесь.
- SQL
- HTTP
- PHP
- Python
- Python-asyncio
- Javascript
- Java
- C#
- Rust
- Typescript
- Go
mysql -h0 -P9306HTTP — это безсостояний протокол, поэтому он не требует специальной фазы подключения. Вы можете просто отправить HTTP-запрос на сервер и получить ответ. Для общения с Manticore через JSON-интерфейс вы можете использовать любую HTTP клиентскую библиотеку на выбранном вами языке программирования для отправки GET или POST запросов на сервер и парсинга JSON ответов:
curl -s "http://localhost:9308/search"// https://github.com/manticoresoftware/manticoresearch-php
require_once __DIR__ . '/vendor/autoload.php';
$config = ['host'=>'127.0.0.1','port'=>9308];
$client = new \Manticoresearch\Client($config);// https://github.com/manticoresoftware/manticoresearch-python
import manticoresearch
config = manticoresearch.Configuration(
host = "http://127.0.0.1:9308"
)
client = manticoresearch.ApiClient(config)
indexApi = manticoresearch.IndexApi(client)
searchApi = manticoresearch.SearchApi(client)
utilsApi = manticoresearch.UtilsApi(client)// https://github.com/manticoresoftware/manticoresearch-python-asyncio
import manticoresearch
config = manticoresearch.Configuration(
host = "http://127.0.0.1:9308"
)
async with manticoresearch.ApiClient(config) as client:
indexApi = manticoresearch.IndexApi(client)
searchApi = manticoresearch.searchApi(client)
utilsApi = manticoresearch.UtilsApi(client)// https://github.com/manticoresoftware/manticoresearch-javascript
var Manticoresearch = require('manticoresearch');
var client= new Manticoresearch.ApiClient()
client.basePath="http://127.0.0.1:9308";
indexApi = new Manticoresearch.IndexApi(client);
searchApi = new Manticoresearch.SearchApi(client);
utilsApi = new Manticoresearch.UtilsApi(client);// https://github.com/manticoresoftware/manticoresearch-java
import com.manticoresearch.client.*;
import com.manticoresearch.client.model.*;
import com.manticoresearch.client.api.*;
...
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("http://127.0.0.1:9308");
...
IndexApi indexApi = new IndexApi(client);
SearchApi searchApi = new UtilsApi(client);
UtilsApi utilsApi = new UtilsApi(client);// https://github.com/manticoresoftware/manticoresearch-net
using System.Net.Http;
...
using ManticoreSearch.Client;
using ManticoreSearch.Api;
using ManticoreSearch.Model;
...
config = new Configuration();
config.BasePath = "http://localhost:9308";
httpClient = new HttpClient();
httpClientHandler = new HttpClientHandler();
...
var indexApi = new IndexApi(httpClient, config, httpClientHandler);
var searchApi = new SearchApi(httpClient, config, httpClientHandler);
var utilsApi = new UtilsApi(httpClient, config, httpClientHandler);// https://github.com/manticoresoftware/manticoresearch-rust
use std::sync::Arc;
use manticoresearch::{
apis::{
{configuration::Configuration,IndexApi,IndexApiClient,SearchApi,SearchApiClient,UtilsApi,UtilsApiClient}
},
};
async fn maticore_connect {
let configuration = Configuration {
base_path: "http://127.0.0.1:9308".to_owned(),
..Default::default(),
};
let api_config = Arc::new(configuration);
let utils_api = UtilsApiClient::new(api_config.clone());
let index_api = IndexApiClient::new(api_config.clone());
let search_api = SearchApiClient::new(api_config.clone());import {
Configuration,
IndexApi,
SearchApi,
UtilsApi
} from "manticoresearch-ts";
...
const config = new Configuration({
basePath: 'http://localhost:9308',
})
const indexApi = new IndexApi(config);
const searchApi = new SearchApi(config);
const utilsApi = new UtilsApi(config);import (
"context"
manticoreclient "github.com/manticoresoftware/manticoresearch-go"
)
...
configuration := manticoreclient.NewConfiguration()
configuration.Servers[0].URL = "http://localhost:9308"
apiClient := manticoreclient.NewAPIClient(configuration)Давайте теперь создадим таблицу с названием "products" с 2 полями:
- title - полнотекстовое поле, которое будет содержать название нашего продукта
- price - типа "float"
Обратите внимание, что можно не создавать таблицу явно с помощью оператора create. Для дополнительной информации смотрите Автоматическая схема.
Больше информации о различных способах создания таблиц можно найти в наших обучающих курсах:
- SQL
- HTTP
- PHP
- Python
- Python-asyncio
- Javascript
- Java
- C#
- Rust
- TypeScript
- Go
create table products(title text, price float) morphology='stem_en';POST /cli -d "create table products(title text, price float) morphology='stem_en'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float'],
],['morphology' => 'stem_en']);utilsApi.sql('create table products(title text, price float) morphology=\'stem_en\'')await utilsApi.sql('create table products(title text, price float) morphology=\'stem_en\'')res = await utilsApi.sql('create table products(title text, price float) morphology=\'stem_en\'');utilsApi.sql("create table products(title text, price float) morphology='stem_en'", true);utilsApi.Sql("create table products(title text, price float) morphology='stem_en'", true);utils_api.sql("create table products(title text, price float) morphology='stem_en'", Some(true)).await;res = await utilsApi.sql('create table products(title text, price float) morphology=\'stem_en\'');res := apiClient.UtilsAPI.Sql(context.Background()).Body("create table products(title text, price float) morphology='stem_en'").Execute();Query OK, 0 rows affected (0.02 sec){
"total":0,
"error":"",
"warning":""
}- SQL
- JSON
- PHP
- Python
- Python-asyncio
- Javascript
- Java
- C#
- Rust
- TypeScript
- Go
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 или отсутствие id заставляет автоматически генерировать ID.
POST /insert
{
"table":"products",
"doc":
{
"title" : "Crossbody Bag with Tassel",
"price" : 19.85
}
}
POST /insert
{
"table":"products",
"doc":
{
"title" : "microfiber sheet set",
"price" : 19.99
}
}
POST /insert
{
"table":"products",
"doc":
{
"title" : "Pet Hair Remover Glove",
"price" : 7.99
}
}$index->addDocuments([
['title' => 'Crossbody Bag with Tassel', 'price' => 19.85],
['title' => 'microfiber sheet set', 'price' => 19.99],
['title' => 'Pet Hair Remover Glove', 'price' => 7.99]
]);indexApi.insert({"table" : "products", "doc" : {"title" : "Crossbody Bag with Tassel", "price" : 19.85}})
indexApi.insert({"table" : "products", "doc" : {"title" : "microfiber sheet set", "price" : 19.99}})
indexApi.insert({"table" : "products", "doc" : {"title" : "Pet Hair Remover Glove", "price" : 7.99}})await indexApi.insert({"table" : "products", "doc" : {"title" : "Crossbody Bag with Tassel", "price" : 19.85}})
await indexApi.insert({"table" : "products", "doc" : {"title" : "microfiber sheet set", "price" : 19.99}})
await indexApi.insert({"table" : "products", "doc" : {"title" : "Pet Hair Remover Glove", "price" : 7.99}})res = await indexApi.insert({"table" : "products", "doc" : {"title" : "Crossbody Bag with Tassel", "price" : 19.85}});
res = await indexApi.insert({"table" : "products", "doc" : {"title" : "microfiber sheet set", "price" : 19.99}});
res = await indexApi.insert({"table" : "products", "doc" : {"title" : "Pet Hair Remover Glove", "price" : 7.99}});InsertDocumentRequest newdoc = new InsertDocumentRequest();
HashMap<String,Object> doc = new HashMap<String,Object>(){{
put("title","Crossbody Bag with Tassel");
put("price",19.85);
}};
newdoc.index("products").setDoc(doc);
sqlresult = indexApi.insert(newdoc);
newdoc = new InsertDocumentRequest();
doc = new HashMap<String,Object>(){{
put("title","microfiber sheet set");
put("price",19.99);
}};
newdoc.index("products").setDoc(doc);
sqlresult = indexApi.insert(newdoc);
newdoc = new InsertDocumentRequest();
doc = new HashMap<String,Object>(){{
put("title","Pet Hair Remover Glove");
put("price",7.99);
}};
newdoc.index("products").setDoc(doc);
indexApi.insert(newdoc);Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("title","Crossbody Bag with Tassel");
doc.Add("price",19.85);
InsertDocumentRequest insertDocumentRequest = new InsertDocumentRequest(index: "products", doc: doc);
sqlresult = indexApi.Insert(insertDocumentRequest);
doc = new Dictionary<string, Object>();
doc.Add("title","microfiber sheet set");
doc.Add("price",19.99);
insertDocumentRequest = new InsertDocumentRequest(index: "products", doc: doc);
sqlresult = indexApi.Insert(insertDocumentRequest);
doc = new Dictionary<string, Object>();
doc.Add("title","Pet Hair Remover Glove");
doc.Add("price",7.99);
insertDocumentRequest = new InsertDocumentRequest(index: "products", doc: doc);
sqlresult = indexApi.Insert(insertDocumentRequest);let mut doc1 = HashMap::new();
doc1.insert("title".to_string(), serde_json::json!("Crossbody Bag with Tassel"));
doc1.insert("price".to_string(), serde_json::json!(19.85));
let insert_req1 = InsertDocumentRequest::new("products".to_string(), serde_json::json!(doc1));
let insert_res1 = index_api.insert(insert_req1).await;
let mut doc2 = HashMap::new();
doc2.insert("title".to_string(), serde_json::json!("microfiber sheet set"));
doc2.insert("price".to_string(), serde_json::json!(19.99));
let insert_req2 = InsertDocumentRequest::new("products".to_string(), serde_json::json!(doc2));
let insert_res2 = index_api.insert(insert_req2).await;
let mut doc3 = HashMap::new();
doc3.insert("title".to_string(), serde_json::json!("Pet Hair Remover Glove"));
doc3.insert("price".to_string(), serde_json::json!(7.99));
let insert_req3 = InsertDocumentRequest::new("products".to_string(), serde_json::json!(doc3));
let insert_res3 = index_api.insert(insert_req3).await;res = await indexApi.insert({
index: 'test',
id: 1,
doc: { content: 'Text 1', name: 'Doc 1', cat: 1 },
});
res = await indexApi.insert({
index: 'test',
id: 2,
doc: { content: 'Text 2', name: 'Doc 2', cat: 2 },
});
res = await indexApi.insert({
index: 'test',
id: 3,
doc: { content: 'Text 3', name: 'Doc 3', cat: 7 },
});indexDoc := map[string]interface{} {"content": "Text 1", "name": "Doc 1", "cat": 1 }
indexReq := manticoreclient.NewInsertDocumentRequest("products", indexDoc)
indexReq.SetId(1)
apiClient.IndexAPI.Insert(context.Background()).InsertDocumentRequest(*indexReq).Execute()
indexDoc = map[string]interface{} {"content": "Text 2", "name": "Doc 3", "cat": 2 }
indexReq = manticoreclient.NewInsertDocumentRequest("products", indexDoc)
indexReq.SetId(2)
apiClient.IndexAPI.Insert(context.Background()).InsertDocumentRequest(*indexReq).Execute()
indexDoc = map[string]interface{} {"content": "Text 3", "name": "Doc 3", "cat": 7 }
indexReq = manticoreclient.NewInsertDocumentRequest("products", indexDoc)
indexReq.SetId(3)
apiClient.IndexAPI.Insert(context.Background()).InsertDocumentRequest(*indexReq).Execute()Query OK, 3 rows affected (0.01 sec){
"table": "products",
"_id": 0,
"created": true,
"result": "created",
"status": 201
}
{
"table": "products",
"_id": 0,
"created": true,
"result": "created",
"status": 201
}
{
"table": "products",
"_id": 0,
"created": true,
"result": "created",
"status": 201
}Более подробную информацию по теме можно найти здесь:
Давайте найдём один из документов. Запрос, который мы будем использовать — 'remove hair'. Как видите, он находит документ с заголовком 'Pet Hair Remover Glove' и выделяет в нём 'Hair remover', хотя в запросе есть "remove", а не "remover". Это потому, что при создании таблицы мы включили использование английского стемминга (morphology "stem_en").
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
select id, highlight(), price from products where match('remove hair');POST /search
{
"table": "products",
"query": { "match": { "title": "remove hair" } },
"highlight":
{
"fields": ["title"]
}
}$result = $index->search('@title remove hair')->highlight(['title'])->get();
foreach($result as $doc)
{
echo "Doc ID: ".$doc->getId()."\n";
echo "Doc Score: ".$doc->getScore()."\n";
echo "Document fields:\n";
print_r($doc->getData());
echo "Highlights: \n";
print_r($doc->getHighlight());
}searchApi.search({"table":"products","query":{"query_string":"@title remove hair"},"highlight":{"fields":["title"]}})await searchApi.search({"table":"products","query":{"query_string":"@title remove hair"},"highlight":{"fields":["title"]}})res = await searchApi.search({"table":"products","query":{"query_string":"@title remove hair"}"highlight":{"fields":["title"]}});query = new HashMap<String,Object>();
query.put("query_string","@title remove hair");
searchRequest = new SearchRequest();
searchRequest.setIndex("forum");
searchRequest.setQuery(query);
HashMap<String,Object> highlight = new HashMap<String,Object>(){{
put("fields",new String[] {"title"});
}};
searchRequest.setHighlight(highlight);
searchResponse = searchApi.search(searchRequest);object query = new { query_string="@title remove hair" };
var searchRequest = new SearchRequest("products", query);
var highlight = new Highlight();
highlight.Fieldnames = new List<string> {"title"};
searchRequest.Highlight = highlight;
searchResponse = searchApi.Search(searchRequest);let query = SearchQuery {
query_string: Some(serde_json::json!("@title remove hair").into()),
..Default::default()
};
let highlight = Highlight {
fields: Some(serde_json::json!(["title"]).into()),
..Default::default()
};
let search_req = SearchRequest {
table: "products".to_string(),
query: Some(Box::new(query)),
highlight: Some(Box::new(highlight)),
..Default::default(),
};
let search_res = search_api.search(search_req).await;res = await searchApi.search({
index: 'test',
query: { query_string: {'text 1'} },
highlight: {'fields': ['content'] }
});searchRequest := manticoreclient.NewSearchRequest("test")
query := map[string]interface{} {"query_string": "text 1"};
searchRequest.SetQuery(query);
highlightField := manticoreclient.NewHighlightField("content")
fields := []interface{}{ highlightField }
highlight := manticoreclient.NewHighlight()
highlight.SetFields(fields)
searchRequest.SetHighlight(highlight);
res, _, _ := apiClient.SearchAPI.Search(context.Background()).SearchRequest(*searchRequest).Execute()+---------------------+-------------------------------+----------+
| id | highlight() | price |
+---------------------+-------------------------------+----------+
| 1513686608316989452 | Pet <b>Hair Remover</b> Glove | 7.990000 |
+---------------------+-------------------------------+----------+
1 row in set (0.00 sec){
"took": 0,
"timed_out": false,
"hits": {
"total": 1,
"hits": [
{
"_id": 1513686608316989452,
"_score": 1680,
"_source": {
"price": 7.99,
"title": "Pet Hair Remover Glove"
},
"highlight": {
"title": [
"Pet <b>Hair Remover</b> Glove"
]
}
}
]
}
}Doc ID: 1513686608316989452
Doc Score: 1680
Document fields:
Array
(
[price] => 7.99
[title] => Pet Hair Remover Glove
)
Highlights:
Array
(
[title] => Array
(
[0] => Pet <b>Hair Remover</b> Glove
)
)`
{'hits': {'hits': [{u'_id': u'1513686608316989452',
u'_score': 1680,
u'_source': {u'title': u'Pet Hair Remover Glove', u'price':7.99},
u'highlight':{u'title':[u'Pet <b>Hair Remover</b> Glove']}}}],
'total': 1},
'profile': None,
'timed_out': False,
'took': 0}{'hits': {'hits': [{u'_id': u'1513686608316989452',
u'_score': 1680,
u'_source': {u'title': u'Pet Hair Remover Glove', u'price':7.99},
u'highlight':{u'title':[u'Pet <b>Hair Remover</b> Glove']}}}],
'total': 1},
'profile': None,
'timed_out': False,
'took': 0}{"hits": {"hits": [{"_id": 1513686608316989452,
"_score": 1680,
"_source": {"title": "Pet Hair Remover Glove", "price":7.99},
"highlight":{"title":["Pet <b>Hair Remover</b> Glove"]}}],
"total": 1},
"profile": None,
"timed_out": False,
"took": 0}class SearchResponse {
took: 84
timedOut: false
hits: class SearchResponseHits {
total: 1
maxScore: null
hits: [{_id=1513686608316989452, _score=1, _source={price=7.99, title=Pet Hair Remover Glove}, highlight={title=[Pet <b>Hair Remover</b> Glove]}}]
aggregations: null
}
profile: null
}class SearchResponse {
took: 103
timedOut: false
hits: class SearchResponseHits {
total: 1
maxScore: null
hits: [{_id=1513686608316989452, _score=1, _source={price=7.99, title=Pet Hair Remover Glove}, highlight={title=[Pet <b>Hair Remover</b> Glove]}}]
aggregations: null
}
profile: null
}class SearchResponse {
took: 103
timedOut: false
hits: class SearchResponseHits {
total: 1
maxScore: null
hits: [{_id=1513686608316989452, _score=1, _source={price=7.99, title=Pet Hair Remover Glove}, highlight={title=[Pet <b>Hair Remover</b> Glove]}}]
aggregations: null
}
profile: null
}{
"hits":
{
"hits":
[{
"_id": 1,
"_score": 1400,
"_source": {"content":"Text 1","name":"Doc 1","cat":1},
"highlight": {"content":["<b>Text 1</b>"]}
}],
"total": 1
},
"profile": None,
"timed_out": False,
"took": 0
}{
"hits":
{
"hits":
[{
"_id": 1,
"_score": 1400,
"_source": {"content":"Text 1","name":"Doc 1","cat":1},
"highlight": {"content":["<b>Text 1</b>"]}
}],
"total": 1
},
"profile": None,
"timed_out": False,
"took": 0
}Более подробную информацию о различных вариантах поиска в Manticore можно найти в наших обучающих курсах:
Предположим, что теперь мы хотим обновить документ — изменить цену на 18.5. Это можно сделать, отфильтровав по любому полю, но обычно вы знаете id документа и обновляете что-то на его основе.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
update products set price=18.5 where id = 1513686608316989452;POST /update
{
"table": "products",
"id": 1513686608316989452,
"doc":
{
"price": 18.5
}
}$doc = [
'body' => [
'table' => 'products',
'id' => 2,
'doc' => [
'price' => 18.5
]
]
];
$response = $client->update($doc);indexApi = api = manticoresearch.IndexApi(client)
indexApi.update({"table" : "products", "id" : 1513686608316989452, "doc" : {"price":18.5}})indexApi = api = manticoresearch.IndexApi(client)
await indexApi.update({"table" : "products", "id" : 1513686608316989452, "doc" : {"price":18.5}})res = await indexApi.update({"table" : "products", "id" : 1513686608316989452, "doc" : {"price":18.5}});UpdateDocumentRequest updateRequest = new UpdateDocumentRequest();
doc = new HashMap<String,Object >(){{
put("price",18.5);
}};
updateRequest.index("products").id(1513686608316989452L).setDoc(doc);
indexApi.update(updateRequest);Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("price", 18.5);
UpdateDocumentRequest updateDocumentRequest = new UpdateDocumentRequest(index: "products", id: 1513686608316989452L, doc: doc);
indexApi.Update(updateDocumentRequest);let mut doc = HashMap::new();
doc.insert("price".to_string(), serde_json::json!(18.5));
let update_req = UpdateDocumentRequest {
table: serde_json::json!("products"),
doc: serde_json::json!(doc),
id: serde_json::json!(1513686608316989452),
..Default::default(),
};
let update_res = index_api.update(update_req).await;res = await indexApi.update({ index: "test", id: 1, doc: { cat: 10 } });updDoc = map[string]interface{} {"cat": 10}
updRequest = manticoreclient.NewUpdateDocumentRequest("test", updDoc)
updRequest.SetId(1)
res, _, _ = apiClient.IndexAPI.Update(context.Background()).UpdateDocumentRequest(*updRequest).Execute()Query OK, 1 row affected (0.00 sec){
"table": "products",
"_id": 1513686608316989452,
"result": "updated"
}- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
delete from products where price < 10;POST /delete
{
"table": "products",
"query":
{
"range":
{
"price":
{
"lte": 10
}
}
}
}$result = $index->deleteDocuments(new \Manticoresearch\Query\Range('price',['lte'=>10]));indexApi.delete({"table" : "products", "query": {"range":{"price":{"lte":10}}}})await indexApi.delete({"table" : "products", "query": {"range":{"price":{"lte":10}}}})res = await indexApi.delete({"table" : "products", "query": {"range":{"price":{"lte":10}}}});DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
query = new HashMap<String,Object>();
query.put("range",new HashMap<String,Object>(){{
put("price",new HashMap<String,Object>(){{
put("lte",10);
}});
}});
deleteRequest.index("products").setQuery(query);
indexApi.delete(deleteRequest);Dictionary<string, Object> price = new Dictionary<string, Object>();
price.Add("lte", 10);
Dictionary<string, Object> range = new Dictionary<string, Object>();
range.Add("price", price);
DeleteDocumentRequest deleteDocumentRequest = new DeleteDocumentRequest(index: "products", query: range);
indexApi.Delete(deleteDocumentRequest);let mut price_range= HashMap::new();
price_range.insert("lte".to_string(), serde_json::json!(10));
let mut range= HashMap::new();
range.insert("price".to_string(), serde_json::json!(price_range));
let delete_req = DeleteDocumentRequest {
table: "products".to_string(),
query: serde_json::json!(range),
..Default::default(),
};
index_api.delete(delete_req).await;res = await indexApi.delete({
index: 'test',
query: { match: { '*': 'Text 1' } },
});delRequest := manticoreclient.NewDeleteDocumentRequest("test")
matchExpr := map[string]interface{} {"*": "Text 1t"}
delQuery := map[string]interface{} {"match": matchExpr }
delRequest.SetQuery(delQuery)
res, _, _ := apiClient.IndexAPI.Delete(context.Background()).DeleteDocumentRequest(*delRequest).Execute();Query OK, 1 row affected (0.00 sec){
"table": "products",
"deleted": 1
}Array
(
[_index] => products
[deleted] => 1
)После установки сервис Manticore Search не запускается автоматически. Чтобы запустить Manticore, выполните следующую команду:
sudo systemctl start manticore
Чтобы остановить Manticore, выполните следующую команду:
sudo systemctl stop manticore
Сервис Manticore настроен на запуск при загрузке. Вы можете проверить это, выполнив:
sudo systemctl is-enabled manticore
Если вы хотите отключить автоматический запуск Manticore при загрузке, выполните:
sudo systemctl disable manticore
Чтобы включить запуск Manticore при загрузке, выполните:
sudo systemctl enable manticore
Процесс searchd записывает информацию о запуске в журнал systemd. Если ведение журнала systemd включено, вы можете просмотреть записанную информацию с помощью следующей команды:
sudo journalctl -u manticore
systemctl set-environment _ADDITIONAL_SEARCHD_PARAMS позволяет указать пользовательские флаги запуска, с которыми должен запускаться демон Manticore Search. Полный список смотрите здесь.
Например, чтобы запустить Manticore с уровнем логирования debug, вы можете выполнить:
systemctl set-environment _ADDITIONAL_SEARCHD_PARAMS='--logdebug'
systemctl restart manticore
Чтобы отменить это, выполните:
systemctl set-environment _ADDITIONAL_SEARCHD_PARAMS=''
systemctl restart manticore
Обратите внимание, что переменные окружения systemd сбрасываются при перезагрузке сервера.
Manticore можно запускать и останавливать с помощью команд service:
sudo service manticore start
sudo service manticore stop
Чтобы включить sysV сервис при загрузке на системах RedHat, выполните:
chkconfig manticore on
Чтобы включить sysV сервис при загрузке на системах Debian (включая Ubuntu), выполните:
update-rc.d manticore defaults
Обратите внимание, что searchd запускается системой инициализации от имени пользователя manticore, и все файлы, созданные сервером, будут принадлежать этому пользователю. Если searchd запущен, например, от имени пользователя root, права на файлы изменятся, что может привести к проблемам при повторном запуске searchd как сервиса.
Вы также можете запустить Manticore Search, вызвав searchd (исполняемый файл сервера Manticore Search) напрямую:
searchd [OPTIONS]
Обратите внимание, что без указания пути к файлу конфигурации searchd попытается найти его в нескольких местах в зависимости от операционной системы.
Опции, доступные для searchd во всех операционных системах:
-
--help(-hдля краткости) выводит список всех параметров, которые можно использовать в вашей конкретной сборкеsearchd. -
--version(-vдля краткости) показывает информацию о версии Manticore Search. -
--config <file>(-c <file>для краткости) указываетsearchdиспользовать указанный файл в качестве конфигурации. -
--stopиспользуется для асинхронной остановкиsearchd, используя данные из файла PID, указанного в конфигурационном файле Manticore. Поэтому вам также может понадобиться указатьsearchd, какой конфигурационный файл использовать с помощью опции--config. Пример:$ searchd --config /etc/manticoresearch/manticore.conf --stop -
--stopwaitиспользуется для синхронной остановкиsearchd.--stopпо сути сообщает запущенному экземпляру выйти (отправляя ему SIGTERM) и сразу возвращается.--stopwaitтакже попытается дождаться, пока запущенный экземплярsearchdдействительно завершит остановку (например, сохранит все ожидающие изменения атрибутов) и выйдет. Пример:$ searchd --config /etc/manticoresearch/manticore.conf --stopwaitВозможные коды выхода:
- 0 при успешном завершении
- 1 если не удалось подключиться к запущенному серверу searchd
- 2 если сервер сообщил об ошибке во время остановки
- 3 если сервер аварийно завершился во время остановки
-
Команда
--statusиспользуется для запроса статуса запущенного экземпляраsearchdс использованием данных подключения из (опционально) предоставленного конфигурационного файла. Она попытается подключиться к запущенному экземпляру, используя первый найденный UNIX-сокет или TCP-порт из конфигурационного файла. При успехе она запросит ряд значений счетчиков статуса и производительности и выведет их. Вы также можете использовать команду SHOW STATUS для доступа к тем же счетчикам через SQL-протокол. Примеры:$ searchd --status $ searchd --config /etc/manticoresearch/manticore.conf --status -
--pidfileиспользуется для явного принудительного использования файла PID (где хранится идентификационный номер процессаsearchd), несмотря на любые другие опции отладки, которые говорят обратное (например,--console). Это опция для отладки.$ searchd --console --pidfile -
--consoleиспользуется для принудительного запускаsearchdв консольном режиме. Обычно Manticore работает как обычное серверное приложение и записывает информацию в лог-файлы (как указано в конфигурационном файле). Однако при отладке проблем с конфигурацией или самим сервером, или при попытке диагностировать трудноуловимые проблемы, может быть удобнее заставить его выводить информацию напрямую в консоль/командную строку, из которой он вызывается. Запуск в консольном режиме также означает, что процесс не будет форкаться (поиск будет выполняться последовательно), и логи не будут записываться в файлы. (Следует отметить, что консольный режим не является предназначенным способом запускаsearchd.) Вы можете вызвать его так:$ searchd --config /etc/manticoresearch/manticore.conf --console -
Опции
--logdebug,--logreplication,--logdebugvи--logdebugvvвключают дополнительный отладочный вывод в лог сервера. Они отличаются уровнем подробности логирования. Это опции для отладки и обычно не должны быть включены, так как могут сильно засорять лог. Их можно временно использовать по запросу для помощи в сложных сессиях отладки. -
--iostatsиспользуется вместе с опциями логирования (должен быть активированquery_logвmanticore.conf), чтобы предоставить более подробную информацию по каждой операции ввода/вывода, выполненной в ходе запроса, с небольшим снижением производительности и увеличением размера логов. Статистика ввода/вывода не включает информацию о операциях ввода/вывода для атрибутов, так как они загружаются с помощью mmap. Для включения можно запуститьsearchdтак:$ searchd --config /etc/manticoresearch/manticore.conf --iostats -
--cpustatsиспользуется для предоставления отчета о фактическом времени работы CPU (в дополнение к реальному времени) как в файле журнала запросов (для каждого запроса), так и в отчете о статусе (агрегированном). Зависит от системного вызова Linuxclock_gettime()или использует менее точный вызов на некоторых системах. Вы можете запуститьsearchdтак:$ searchd --config /etc/manticoresearch/manticore.conf --cpustats -
--port portnumber(-pдля краткости) используется для указания порта, на котором Manticore должен слушать запросы бинарного протокола, обычно для целей отладки. Обычно по умолчанию используется 9312, но иногда нужно запустить на другом порту. Указание на командной строке переопределит значение из конфигурационного файла. Допустимый диапазон — от 0 до 65535, но порты с номерами 1024 и ниже обычно требуют привилегированного аккаунта для запуска.Пример использования:
$ searchd --port 9313 -
--listen ( address ":" port | port | path ) [ ":" protocol ](или-lдля краткости) работает как--port, но позволяет указать не только порт, но полный путь, IP-адрес и порт, или путь Unix-доменного сокета, на которомsearchdбудет слушать. Другими словами, вы можете указать либо IP-адрес (или имя хоста) и номер порта, только номер порта, либо путь Unix-сокета. Если указан только номер порта без адреса, searchd будет слушать на всех сетевых интерфейсах. Путь Unix определяется ведущим слэшем. В качестве последнего параметра можно также указать обработчик протокола (listener), который будет использоваться для подключений на этом сокете. Поддерживаемые значения протокола: 'sphinx' и 'mysql' (протокол MySQL, используемый с версии 4.1). -
--force-prereadзапрещает серверу обслуживать любые входящие подключения до завершения предварительной загрузки файлов таблиц. По умолчанию при запуске сервер принимает подключения, пока файлы таблиц лениво загружаются в память. Эта опция расширяет поведение и заставляет ждать, пока файлы не будут загружены. -
--index (--table) <table>(или-i (-t) <table>для краткости) заставляет этот экземплярsearchdобслуживать только указанную таблицу. Как и--portвыше, это обычно используется для отладки; более долгосрочные изменения обычно применяются непосредственно в конфигурационном файле. -
--strip-pathудаляет пути из всех имен файлов, на которые ссылается таблица (стоп-слова, словоформы, исключения и т.д.). Это полезно для использования таблиц, созданных на другой машине с возможно другой структурой путей. -
--replay-flags=<OPTIONS>переключатель можно использовать для указания списка дополнительных опций воспроизведения бинарного лога. Поддерживаемые опции:accept-desc-timestamp, игнорировать убывающие временные метки транзакций и воспроизводить такие транзакции в любом случае (поведение по умолчанию — завершение с ошибкой).ignore-open-errors, игнорировать отсутствующие файлы binlog (поведение по умолчанию — завершение с ошибкой).ignore-trx-errors, игнорировать любые ошибки транзакций и пропускать текущий файл binlog (поведение по умолчанию — завершение с ошибкой).ignore-all-errors, игнорировать любые описанные выше ошибки (поведение по умолчанию — завершение с ошибкой).
Пример:
$ searchd --replay-flags=accept-desc-timestamp -
--coredumpиспользуется для включения сохранения core-файла или минидампа сервера при сбое. По умолчанию отключено для ускорения перезапуска сервера после сбоя. Полезно для целей отладки.$ searchd --config /etc/manticoresearch/manticore.conf --coredump -
--new-clusterинициализирует кластер репликации и делает сервер эталонным узлом с защитой перезапуска кластера. В Linux также можно запуститьmanticore_new_cluster. Он запустит Manticore в режиме--new-clusterчерез systemd. -
--new-cluster-forceинициализирует кластер репликации и делает сервер эталонным узлом, обходя защиту перезапуска кластера. В Linux также можно запуститьmanticore_new_cluster --force. Он запустит Manticore в режиме--new-cluster-forceчерез systemd. -
--mockstackанализирует и сообщает необходимые размеры стека для рекурсивной оценки выражений, операций сопоставления с образцом и обработки фильтров. Эта опция отладки выводит рассчитанные требования к стеку в консоль для целей оптимизации. Вывод содержит переменные окружения, которые можно использовать для настройки требований к стеку для различных операций.Пример:
$ searchd --mockstack Manticore 7.4.7 e90b5afbb@25032706 dev (columnar 4.1.2 15bbcc7@25031206) (secondary 4.1.2 15bbcc7@25031206) (knn 4.1.2 15bbcc7@25031206) Copyright (c) 2001-2016, Andrew Aksyonoff Copyright (c) 2008-2016, Sphinx Technologies Inc (http://sphinxsearch.com) Copyright (c) 2017-2025, Manticore Software LTD (https://manticoresearch.com) export MANTICORE_KNOWN_CREATE_SIZE=200 export MANTICORE_START_KNOWN_CREATE_SIZE=4504 export MANTICORE_KNOWN_EXPR_SIZE=16 export MANTICORE_START_KNOWN_EXPR_SIZE=200 export MANTICORE_NONE=32 export MANTICORE_START_NONE=104 export MANTICORE_KNOWN_FILTER_SIZE=224 export MANTICORE_START_KNOWN_FILTER_SIZE=11192 export MANTICORE_KNOWN_MATCH_SIZE=320 export MANTICORE_START_KNOWN_MATCH_SIZE=14552 export NO_STACK_CALCULATION=1
Существуют некоторые опции для searchd, специфичные для платформ Windows, касающиеся работы как службы, и доступны только в бинарных файлах для Windows.
Обратите внимание, что в Windows searchd по умолчанию работает в режиме --console, если только вы не установите его как службу.
-
--installустанавливаетsearchdкак службу в Microsoft Management Console (Панель управления / Администрирование / Службы). Любые другие параметры, указанные в командной строке вместе с--install, также будут частью командной строки при последующих запусках службы. Например, при вызовеsearchdвам, вероятно, также потребуется указать конфигурационный файл с помощью--config, и вы сделаете это вместе с--install. После вызова стандартные средства запуска/остановки станут доступны через консоль управления, так что любые методы запуска, остановки и перезапуска служб также применимы кsearchd. Пример:C:\WINDOWS\system32> C:\Manticore\bin\searchd.exe --install --config C:\Manticore\manticore.confЕсли вы хотите получать статистику ввода-вывода каждый раз при запуске
searchd, необходимо указать опцию в той же строке, что и команда--install, следующим образом:C:\WINDOWS\system32> C:\Manticore\bin\searchd.exe --install --config C:\Manticore\manticore.conf --iostats -
--deleteудаляет службу из Microsoft Management Console и других мест, где регистрируются службы, после предыдущей установки с помощью--install. Обратите внимание, что это не удаляет программное обеспечение и не удаляет таблицы. Это означает, что служба не будет вызываться из системы служб и не будет запускаться при следующем старте машины. Если служба в данный момент запущена, текущий экземпляр не будет завершён (до следующей перезагрузки или до вызова--stop). Если служба была установлена с пользовательским именем (с помощью--servicename), то при удалении нужно указать то же имя с--servicename. Пример:C:\WINDOWS\system32> C:\Manticore\bin\searchd.exe --delete -
--servicename <name>применяет указанное имя кsearchdпри установке или удалении службы, как оно будет отображаться в Консоли управления; по умолчанию это будет searchd, но если развертывание происходит на серверах, где в систему могут входить несколько администраторов, или на системе с несколькими экземплярамиsearchd, может быть применимо более описательное имя. Обратите внимание, что если не использовать вместе с--installили--delete, эта опция ничего не делает. Пример:C:\WINDOWS\system32> C:\Manticore\bin\searchd.exe --install --config C:\Manticore\manticore.conf --servicename ManticoreSearch -
--ntservice— это опция, которая передается Microsoft Management Console вsearchdдля запуска его как службы на платформах Windows. Обычно нет необходимости вызывать это напрямую; это обычно вызывается Windows при запуске службы, хотя теоретически вы можете вызвать это как обычную службу из командной строки (в дополнение к--console). -
--safetraceзаставляетsearchdиспользовать только системный вызов backtrace() в отчетах о сбоях. В некоторых (редких) сценариях это может быть «более безопасным» способом получения такого отчета. Это опция для отладки. -
Переключатель
--nodetach(только для Linux) указываетsearchdне отсоединяться в фоновый режим. Это также приведет к выводу записей журнала в консоль. Обработка запросов работает как обычно. Это опция для отладки и может быть полезна при запуске Manticore в контейнере Docker для захвата его вывода.
Manticore использует plugin_dir для хранения и использования плагинов Manticore Buddy. По умолчанию это значение доступно пользователю "manticore" в стандартной установке. Однако, если вы запускаете демон searchd вручную под другим пользователем, демон может не иметь доступа к plugin_dir. Чтобы решить эту проблему, убедитесь, что вы указали plugin_dir в общем разделе, к которому пользователь, запускающий демон searchd, имеет права на запись.
searchd поддерживает ряд сигналов:
SIGTERM— инициирует корректное завершение работы. Новые запросы обрабатываться не будут, но уже начатые запросы не будут принудительно прерваны.SIGHUP— инициирует ротацию таблиц. В зависимости от значения настройки seamless_rotate новые запросы могут быть кратковременно приостановлены; клиенты получат временные ошибки.SIGUSR1— принудительно открывает заново файлы журнала searchd и журнала запросов, что позволяет выполнять ротацию файлов журнала.
MANTICORE_TRACK_DAEMON_SHUTDOWN=1включает подробное логирование при завершении работы searchd. Это полезно в случае проблем с завершением работы, например, когда Manticore слишком долго завершает работу или зависает в процессе завершения.