Вы можете легко установить и запустить 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.
brew install manticoresearch
brew services start manticoresearchdocker pull manticoresearch/manticore
docker run --name manticore -p9306:9306 -p9308:9308 -p9312:9312 -d manticoresearch/manticoreДля сохранения вашего каталога данных прочитайте как использовать Docker Manticore в production
По умолчанию 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. Это можно сделать, отфильтровав по любому полю, но обычно вы знаете идентификатор документа и обновляете что-то на его основе.
- 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. -
--quiet(сокращённо-q) подавляет вывод при запуске, кроме ошибок (баннер и сообщения о предварительном кэшировании). -
--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) для предоставления более подробной информации по каждому запросу о операциях ввода/вывода, выполненных в ходе этого запроса, с небольшим снижением производительности и немного большими журналами. Статистика IO не включает информацию об операциях IO для атрибутов, так как они загружаются с помощью mmap. Чтобы включить её, вы можете запуститьsearchdследующим образом:$ searchd --config /etc/manticoresearch/manticore.conf --iostats -
--cpustatsиспользуется для предоставления отчёта о фактическом времени процессора (в дополнение к реальному времени) как в файле журнала запросов (для каждого заданного запроса), так и в отчёте о статусе (агрегированном). Это зависит от системного вызова 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-путь идентифицируется начальным слэшем. В качестве последнего параметра вы также можете указать обработчик протокола (слушатель), который будет использоваться для соединений на этом сокете. Поддерживаемые значения протокола: '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 в секции common, куда пользователь, запускающий демон searchd, имеет права записи.
searchd поддерживает несколько сигналов:
SIGTERM- Инициирует корректное завершение работы. Новые запросы не будут обрабатываться, но уже начатые запросы не будут принудительно прерваны.SIGHUP- Инициирует ротацию таблиц. В зависимости от значения настройки seamless_rotate, новые запросы могут быть ненадолго приостановлены; клиенты будут получать временные ошибки.SIGUSR1- Принудительно переоткрывает файлы журнала searchd и журнала запросов, что позволяет выполнить ротацию файлов журналов.
MANTICORE_TRACK_DAEMON_SHUTDOWN=1включает подробное логирование во время завершения работы searchd. Это полезно в случае некоторых проблем с завершением работы, например, когда Manticore слишком долго завершает работу или зависает в процессе завершения.