REPLACE работает аналогично INSERT, но предварительно помечает предыдущий документ с таким же ID как удалённый перед вставкой нового.
Если вам нужны обновления на месте, пожалуйста, смотрите этот раздел.
Синтаксис SQL-запроса REPLACE следующий:
Для замены всего документа:
REPLACE INTO table [(column1, column2, ...)]
VALUES (value1, value2, ...)
[, (...)]
Столбцы, явно не включённые в SQL-запрос, устанавливаются в значения по умолчанию, такие как 0 или пустая строка, в зависимости от их типа данных.
Для замены только выбранных полей:
REPLACE INTO table
SET field1=value1[, ..., fieldN=valueN]
WHERE id = <id>
Обратите внимание, что в этом режиме фильтровать можно только по id.
ПРИМЕЧАНИЕ: Частичная замена требует Manticore Buddy. Если не работает, убедитесь, что Buddy установлен.
Для замены из SELECT:
REPLACE INTO table
SELECT ... FROM source
REPLACE INTO table (column1, column2, column3)
SELECT ... FROM source
ПРИМЕЧАНИЕ: Этот синтаксис требует Manticore Buddy. Если он не работает, убедитесь, что Buddy установлен.
Подробнее о UPDATE и частичной замене REPLACE читайте здесь.
Смотрите примеры для более подробной информации.
-
/replace:POST /replace { "table": "<table name>", "id": <document id>, "doc": { "<field1>": <value1>, ... "<fieldN>": <valueN> } }/index— алиас для этого эндпоинта и работает так же. -
Elasticsearch-подобный эндпоинт
<table>/_doc/<id>:PUT/POST /<table name>/_doc/<id> { "<field1>": <value1>, ... "<fieldN>": <valueN> }ПРИМЕЧАНИЕ: Elasticsearch-подобная замена требует Manticore Buddy. Если не работает, убедитесь, что Buddy установлен.
-
Частичная замена:
POST /<{table | cluster:table}>/_update/<id> { "<field1>": <value1>, ... "<fieldN>": <valueN> }<table name>может быть просто названием таблицы или в форматеcluster:table. Это позволяет делать обновления в конкретном кластере, если это необходимо.ПРИМЕЧАНИЕ: Частичная замена требует Manticore Buddy. Если не работает, убедитесь, что Buddy установлен.
Смотрите примеры для более подробной информации.
- SQL
- REPLACE SET
- REPLACE ... SELECT
- JSON
- Elasticsearch-like
- Elasticsearch-like partial
- Elasticsearch-like partial in cluster
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
REPLACE INTO products VALUES(1, "document one", 10);REPLACE INTO products SET description='HUAWEI Matebook 15', price=10 WHERE id = 55;CREATE TABLE products_src (id int, title text, price float, category_id int);
CREATE TABLE products (id int, title text, price float, category_id int);
INSERT INTO products_src VALUES
(1, 'Notebook Stand', 45.00, 10),
(2, 'USB-C Hub', 79.90, 12),
(3, 'Wireless Mouse', 129.00, 10);
REPLACE INTO products_a (id, price)
SELECT id, price FROM products_src;
REPLACE INTO products_b
SELECT * FROM products_src;
REPLACE INTO products_c (id, title, category_id)
SELECT id, title, category_id
FROM products_src
WHERE price >= 100;POST /replace
-H "Content-Type: application/x-ndjson" -d '
{
"table":"products",
"id":1,
"doc":
{
"title":"product one",
"price":10
}
}
'ПРИМЕЧАНИЕ: Elasticsearch-подобная замена требует Manticore Buddy. Если не работает, убедитесь, что Buddy установлен.
PUT /products/_doc/2
{
"title": "product two",
"price": 20
}
POST /products/_doc/3
{
"title": "product three",
"price": 10
}ПРИМЕЧАНИЕ: Частичная замена требует Manticore Buddy. Если не работает, убедитесь, что Buddy установлен.
POST /products/_update/55
{
"doc": {
"description": "HUAWEI Matebook 15",
"price": 10
}
}POST /cluster_name:products/_update/55
{
"doc": {
"description": "HUAWEI Matebook 15",
"price": 10
}
}$index->replaceDocument([
'title' => 'document one',
'price' => 10
],1);indexApi.replace({"table" : "products", "id" : 1, "doc" : {"title" : "document one","price":10}})await indexApi.replace({"table" : "products", "id" : 1, "doc" : {"title" : "document one","price":10}})res = await indexApi.replace({"table" : "products", "id" : 1, "doc" : {"title" : "document one","price":10}});docRequest = new InsertDocumentRequest();
HashMap<String,Object> doc = new HashMap<String,Object>(){{
put("title","document one");
put("price",10);
}};
docRequest.index("products").id(1L).setDoc(doc);
sqlresult = indexApi.replace(docRequest);Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("title", "document one");
doc.Add("price", 10);
InsertDocumentRequest docRequest = new InsertDocumentRequest(index: "products", id: 1, doc: doc);
var sqlresult = indexApi.replace(docRequest);let mut doc = HashMap::new();
doc.insert("title".to_string(), serde_json::json!("document one"));
doc.insert("price".to_string(), serde_json::json!(10));
let insert_req = InsertDocumentRequest::new("products".to_string(), serde_json::json!(doc));
let insert_res = index_api.replace(insert_req).await;res = await indexApi.replace({
index: 'test',
id: 1,
doc: { content: 'Text 11', name: 'Doc 11', cat: 3 },
});replaceDoc := map[string]interface{} {"content": "Text 11", "name": "Doc 11", "cat": 3}
replaceRequest := manticoreclient.NewInsertDocumentRequest("test", replaceDoc)
replaceRequest.SetId(1)
res, _, _ := apiClient.IndexAPI.Replace(context.Background()).InsertDocumentRequest(*replaceRequest).Execute()Query OK, 1 row affected (0.00 sec)Query OK, 1 row affected (0.00 sec)Query OK, 3 rows affected (0.00 sec){
"table":"products",
"_id":1,
"created":false,
"result":"updated",
"status":200
}{
"_id":2,
"table":"products",
"_primary_term":1,
"_seq_no":0,
"_shards":{
"failed":0,
"successful":1,
"total":1
},
"_type":"_doc",
"_version":1,
"result":"updated"
}
{
"_id":3,
"table":"products",
"_primary_term":1,
"_seq_no":0,
"_shards":{
"failed":0,
"successful":1,
"total":1
},
"_type":"_doc",
"_version":1,
"result":"updated"
}{
"table":"products",
"updated":1
}{
"table":"products",
"updated":1
}Array(
[_index] => products
[_id] => 1
[created] => false
[result] => updated
[status] => 200
){'created': False,
'found': None,
'id': 1,
'table': 'products',
'result': 'updated'}{'created': False,
'found': None,
'id': 1,
'table': 'products',
'result': 'updated'}{"table":"products","_id":1,"result":"updated"}class SuccessResponse {
index: products
id: 1
created: false
result: updated
found: null
}class SuccessResponse {
index: products
id: 1
created: false
result: updated
found: null
}class SuccessResponse {
index: products
id: 1
created: false
result: updated
found: null
}{
"table":"test",
"_id":1,
"created":false
"result":"updated"
"status":200
}{
"table":"test",
"_id":1,
"created":false
"result":"updated"
"status":200
}REPLACE доступен для реального времени и перколационных таблиц. В обычных таблицах заменить данные нельзя.
Когда вы запускаете REPLACE, предыдущий документ не удаляется, а помечается как удалённый, поэтому размер таблицы растёт до тех пор, пока не произойдёт слияние чанков. Чтобы форсировать слияние чанков, используйте оператор OPTIMIZE.
Вы можете заменить несколько документов одновременно. Подробнее смотрите в разделе массовое добавление документов.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
REPLACE INTO products(id,title,tag) VALUES (1, 'doc one', 10), (2,' doc two', 20);POST /bulk
-H "Content-Type: application/x-ndjson" -d '
{ "replace" : { "table" : "products", "id":1, "doc": { "title": "doc one", "tag" : 10 } } }
{ "replace" : { "table" : "products", "id":2, "doc": { "title": "doc two", "tag" : 20 } } }
'$index->replaceDocuments([
[
'id' => 1,
'title' => 'document one',
'tag' => 10
],
[
'id' => 2,
'title' => 'document one',
'tag' => 20
]
);indexApi = manticoresearch.IndexApi(client)
docs = [ \
{"replace": {"table" : "products", "id" : 1, "doc" : {"title" : "document one"}}}, \
{"replace": {"table" : "products", "id" : 2, "doc" : {"title" : "document two"}}} ]
api_resp = indexApi.bulk('\n'.join(map(json.dumps,docs)))indexApi = manticoresearch.IndexApi(client)
docs = [ \
{"replace": {"table" : "products", "id" : 1, "doc" : {"title" : "document one"}}}, \
{"replace": {"table" : "products", "id" : 2, "doc" : {"title" : "document two"}}} ]
api_resp = await indexApi.bulk('\n'.join(map(json.dumps,docs)))docs = [
{"replace": {"table" : "products", "id" : 1, "doc" : {"title" : "document one"}}},
{"replace": {"table" : "products", "id" : 2, "doc" : {"title" : "document two"}}} ];
res = await indexApi.bulk(docs.map(e=>JSON.stringify(e)).join('\n'));body = "{\"replace\": {\"index\" : \"products\", \"id\" : 1, \"doc\" : {\"title\" : \"document one\"}}}" +"\n"+
"{\"replace\": {\"index\" : \"products\", \"id\" : 2, \"doc\" : {\"title\" : \"document two\"}}}"+"\n" ;
indexApi.bulk(body);string body = "{\"replace\": {\"index\" : \"products\", \"id\" : 1, \"doc\" : {\"title\" : \"document one\"}}}" +"\n"+
"{\"replace\": {\"index\" : \"products\", \"id\" : 2, \"doc\" : {\"title\" : \"document two\"}}}"+"\n" ;
indexApi.Bulk(body);string body = r#"{"replace": {"index" : "products", "id" : 1, "doc" : {"title" : "document one"}}}
{"replace": {"index" : "products", "id" : 2, "doc" : {"title" : "document two"}}}
"#;
index_api.bulk(body).await;replaceDocs = [
{
replace: {
index: 'test',
id: 1,
doc: { content: 'Text 11', cat: 1, name: 'Doc 11' },
},
},
{
replace: {
index: 'test',
id: 2,
doc: { content: 'Text 22', cat: 9, name: 'Doc 22' },
},
},
];
res = await indexApi.bulk(
replaceDocs.map((e) => JSON.stringify(e)).join("\n")
);body := "{\"replace\": {\"index\": \"test\", \"id\": 1, \"doc\": {\"content\": \"Text 11\", \"name\": \"Doc 11\", \"cat\": 1 }}}" + "\n" +
"{\"replace\": {\"index\": \"test\", \"id\": 2, \"doc\": {\"content\": \"Text 22\", \"name\": \"Doc 22\", \"cat\": 9 }}}" +"\n";
res, _, _ := apiClient.IndexAPI.Bulk(context.Background()).Body(body).Execute()Query OK, 2 rows affected (0.00 sec){
"items":
[
{
"replace":
{
"table":"products",
"_id":1,
"created":false,
"result":"updated",
"status":200
}
},
{
"replace":
{
"table":"products",
"_id":2,
"created":false,
"result":"updated",
"status":200
}
}
],
"errors":false
}Array(
[items] =>
Array(
Array(
[_index] => products
[_id] => 2
[created] => false
[result] => updated
[status] => 200
)
Array(
[_index] => products
[_id] => 2
[created] => false
[result] => updated
[status] => 200
)
)
[errors => false
){'error': None,
'items': [{u'replace': {u'_id': 1,
u'table': u'products',
u'created': False,
u'result': u'updated',
u'status': 200}},
{u'replace': {u'_id': 2,
u'table': u'products',
u'created': False,
u'result': u'updated',
u'status': 200}}]}{'error': None,
'items': [{u'replace': {u'_id': 1,
u'table': u'products',
u'created': False,
u'result': u'updated',
u'status': 200}},
{u'replace': {u'_id': 2,
u'table': u'products',
u'created': False,
u'result': u'updated',
u'status': 200}}]}{"items":[{"replace":{"table":"products","_id":1,"created":false,"result":"updated","status":200}},{"replace":{"table":"products","_id":2,"created":false,"result":"updated","status":200}}],"errors":false}class BulkResponse {
items: [{replace={_index=products, _id=1, created=false, result=updated, status=200}}, {replace={_index=products, _id=2, created=false, result=updated, status=200}}]
error: null
additionalProperties: {errors=false}
}class BulkResponse {
items: [{replace={_index=products, _id=1, created=false, result=updated, status=200}}, {replace={_index=products, _id=2, created=false, result=updated, status=200}}]
error: null
additionalProperties: {errors=false}
}class BulkResponse {
items: [{replace={_index=products, _id=1, created=false, result=updated, status=200}}, {replace={_index=products, _id=2, created=false, result=updated, status=200}}]
error: null
additionalProperties: {errors=false}
}{
"items":
[
{
"replace":
{
"table":"test",
"_id":1,
"created":false,
"result":"updated",
"status":200
}
},
{
"replace":
{
"table":"test",
"_id":2,
"created":false,
"result":"updated",
"status":200
}
}
],
"errors":false
}{
"items":
[
{
"replace":
{
"table":"test",
"_id":1,
"created":false,
"result":"updated",
"status":200
}
},
{
"replace":
{
"table":"test",
"_id":2,
"created":false,
"result":"updated",
"status":200
}
}
],
"errors":false
}Команда UPDATE изменяет значения атрибутов, хранящихся построчно, у существующих документов в указанной таблице на новые значения. Обратите внимание, что нельзя обновить содержимое полнотекстового поля или колоночного атрибута. Если такая необходимость есть, используйте REPLACE.
Обновление атрибутов поддерживается для RT, PQ и обычных таблиц. Все типы атрибутов могут быть обновлены, при условии что они хранятся в построчном хранилище.
Обратите внимание, что идентификатор документа не может быть обновлен.
Важно знать, что обновление атрибута отключает его вторичный индекс. Если непрерывность вторичного индекса критически важна, рассмотрите возможность полной или частичной замены документа.
Подробнее о UPDATE и частичном REPLACE читайте здесь.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
UPDATE products SET enabled=0 WHERE id=10;POST /update
{
"table":"products",
"id":10,
"doc":
{
"enabled":0
}
}$index->updateDocument([
'enabled'=>0
],10);indexApi = api = manticoresearch.IndexApi(client)
indexApi.update({"table" : "products", "id" : 1, "doc" : {"price":10}})indexApi = api = manticoresearch.IndexApi(client)
await indexApi.update({"table" : "products", "id" : 1, "doc" : {"price":10}})res = await indexApi.update({"table" : "products", "id" : 1, "doc" : {"price":10}});UpdateDocumentRequest updateRequest = new UpdateDocumentRequest();
doc = new HashMap<String,Object >(){{
put("price",10);
}};
updateRequest.index("products").id(1L).setDoc(doc);
indexApi.update(updateRequest);Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("price", 10);
UpdateDocumentRequest updateRequest = new UpdateDocumentRequest(index: "products", id: 1, doc: doc);
indexApi.Update(updateRequest);let mut doc = HashMap::new();
doc.insert("price".to_string(), serde_json::json!(10));
let update_req = UpdateDocumentRequest {
table: serde_json::json!("products"),
doc: serde_json::json!(doc),
id: serde_json::json!(1),
..Default::default(),
};
let update_res = index_api.update(update_req).await;res = await indexApi.update({ index: "test", id: 1, doc: { cat: 10 } });updateDoc = map[string]interface{} {"cat":10}
updateRequest = openapiclient.NewUpdateDocumentRequest("test", updateDoc)
updateRequest.SetId(1)
res, _, _ = apiClient.IndexAPI.Update(context.Background()).UpdateDocumentRequest(*updateRequest).Execute()Query OK, 1 row affected (0.00 sec){
"table":"products",
"updated":1
}Array(
[_index] => products
[_id] => 10
[result] => updated
){'id': 1, 'table': 'products', 'result': 'updated', 'updated': None}{'id': 1, 'table': 'products', 'result': 'updated', 'updated': None}{"table":"products","_id":1,"result":"updated"}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}{
"table":"test",
"_id":1,
"result":"updated"
}{
"table":"test",
"_id":1,
"result":"updated"
}Несколько атрибутов могут быть обновлены в одном операторе. Пример:
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
UPDATE products
SET price=100000000000,
coeff=3465.23,
tags1=(3,6,4),
tags2=()
WHERE MATCH('phone') AND enabled=1;POST /update
{
"table":"products",
"doc":
{
"price":100000000000,
"coeff":3465.23,
"tags1":[3,6,4],
"tags2":[]
},
"query":
{
"match": { "*": "phone" },
"equals": { "enabled": 1 }
}
}$query= new BoolQuery();
$query->must(new Match('phone','*'));
$query->must(new Equals('enabled',1));
$index->updateDocuments([
'price' => 100000000000,
'coeff' => 3465.23,
'tags1' => [3,6,4],
'tags2' => []
],
$query
);indexApi = api = manticoresearch.IndexApi(client)
indexApi.update({"table" : "products", "id" : 1, "doc" : {
"price": 100000000000,
"coeff": 3465.23,
"tags1": [3,6,4],
"tags2": []}})indexApi = api = manticoresearch.IndexApi(client)
await indexApi.update({"table" : "products", "id" : 1, "doc" : {
"price": 100000000000,
"coeff": 3465.23,
"tags1": [3,6,4],
"tags2": []}})res = await indexApi.update({"table" : "products", "id" : 1, "doc" : {
"price": 100000000000,
"coeff": 3465.23,
"tags1": [3,6,4],
"tags2": []}});UpdateDocumentRequest updateRequest = new UpdateDocumentRequest();
doc = new HashMap<String,Object >(){{
put("price",10);
put("coeff",3465.23);
put("tags1",new int[]{3,6,4});
put("tags2",new int[]{});
}};
updateRequest.index("products").id(1L).setDoc(doc);
indexApi.update(updateRequest);Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("price", 10);
doc.Add("coeff", 3465.23);
doc.Add("tags1", new List<int> {3,6,4});
doc.Add("tags2", new List<int> {});
UpdateDocumentRequest updateRequest = new UpdateDocumentRequest(index: "products", id: 1, doc: doc);
indexApi.Update(updateRequest);let mut doc = HashMap::new();
doc.insert("price".to_string(), serde_json::json!(10));
doc.insert("coeff".to_string(), serde_json::json!(3465.23));
doc.insert("tags1".to_string(), serde_json::json!([3,6,4]));
doc.insert("tags2".to_string(), serde_json::json!([]));
let update_req = UpdateDocumentRequest {
table: serde_json::json!("products"),
doc: serde_json::json!(doc),
id: serde_json::json!(1),
..Default::default(),
};
let update_res = index_api.update(update_req).await;res = await indexApi.update({ index: "test", id: 1, doc: { name: "Doc 21", cat: "10" } });updateDoc = map[string]interface{} {"name":"Doc 21", "cat":10}
updateRequest = manticoreclient.NewUpdateDocumentRequest("test", updateDoc)
updateRequest.SetId(1)
res, _, _ = apiClient.IndexAPI.Update(context.Background()).UpdateDocumentRequest(*updateRequest).Execute()Query OK, 148 rows affected (0.0 sec){
"table":"products",
"updated":148
}Array(
[_index] => products
[updated] => 148
){'id': 1, 'table': 'products', 'result': 'updated', 'updated': None}{'id': 1, 'table': 'products', 'result': 'updated', 'updated': None}{"table":"products","_id":1,"result":"updated"}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}{
"table":"test",
"_id":1,
"result":"updated"
}{
"table":"test",
"_id":1,
"result":"updated"
}При присвоении 32-битным атрибутам значений, выходящих за допустимый диапазон, они будут обрезаны до своих младших 32 бит без предупреждения. Например, если вы попытаетесь обновить 32-битное беззнаковое целое значение 4294967297, фактически будет сохранено значение 1, потому что младшие 32 бита числа 4294967297 (0x100000001 в шестнадцатеричной системе) составляют 1 (0x00000001 в шестнадцатеричной системе).
UPDATE может использоваться для выполнения частичных обновлений JSON для числовых типов данных или массивов числовых типов данных. Просто убедитесь, что вы не обновляете целочисленное значение значением с плавающей запятой, так как оно будет округлено.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
insert into products (id, title, meta) values (1,'title','{"tags":[1,2,3]}');
update products set meta.tags[0]=100 where id=1;POST /insert
{
"table":"products",
"id":100,
"doc":
{
"title":"title",
"meta": {
"tags":[1,2,3]
}
}
}
POST /update
{
"table":"products",
"id":100,
"doc":
{
"meta.tags[0]":100
}
}$index->insertDocument([
'title' => 'title',
'meta' => ['tags' => [1,2,3]]
],1);
$index->updateDocument([
'meta.tags[0]' => 100
],1);indexApi = api = manticoresearch.IndexApi(client)
indexApi.update({"table" : "products", "id" : 1, "doc" : {
"meta.tags[0]": 100}})indexApi = api = manticoresearch.IndexApi(client)
await indexApi.update({"table" : "products", "id" : 1, "doc" : {
"meta.tags[0]": 100}})res = await indexApi.update({"table" : "products", "id" : 1, "doc" : {
"meta.tags[0]": 100}});UpdateDocumentRequest updateRequest = new UpdateDocumentRequest();
doc = new HashMap<String,Object >(){{
put("meta.tags[0]",100);
}};
updateRequest.index("products").id(1L).setDoc(doc);
indexApi.update(updateRequest);Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("meta.tags[0]", 100);
UpdateDocumentRequest updateRequest = new UpdateDocumentRequest(index: "products", id: 1, doc: doc);
indexApi.Update(updateRequest);let mut doc = HashMap::new();
doc.insert("meta.tags[0]".to_string(), serde_json::json!(100));
let update_req = UpdateDocumentRequest {
table: serde_json::json!("products"),
doc: serde_json::json!(doc),
id: serde_json::json!(1),
..Default::default(),
};
let update_res = index_api.update(update_req).await;res = await indexApi.update({"table" : "test", "id" : 1, "doc" : { "meta.tags[0]": 100} });updateDoc = map[string]interface{} {"meta.tags[0]":100}
updateRequest = manticoreclient.NewUpdateDocumentRequest("test", updateDoc)
updateRequest.SetId(1)
res, _, _ = apiClient.IndexAPI.Update(context.Background()).UpdateDocumentRequest(*updateRequest).Execute()Query OK, 1 row affected (0.00 sec)
Query OK, 1 row affected (0.00 sec){
"table":"products",
"_id":100,
"created":true,
"result":"created",
"status":201
}
{
"table":"products",
"updated":1
}Array(
[_index] => products
[_id] => 1
[created] => true
[result] => created
)
Array(
[_index] => products
[updated] => 1
){'id': 1, 'table': 'products', 'result': 'updated', 'updated': None}{'id': 1, 'table': 'products', 'result': 'updated', 'updated': None}{"table":"products","_id":1,"result":"updated"}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}{"table":"test","_id":1,"result":"updated"}{
"table":"test",
"_id":1,
"result":"updated"
}Обновление других типов данных или изменение типа свойства в JSON-атрибуте требует полного обновления JSON.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
insert into products values (1,'title','{"tags":[1,2,3]}');
update products set data='{"tags":["one","two","three"]}' where id=1;POST /insert
{
"table":"products",
"id":1,
"doc":
{
"title":"title",
"data":"{\"tags\":[1,2,3]}"
}
}
POST /update
{
"table":"products",
"id":1,
"doc":
{
"data":"{\"tags\":[\"one\",\"two\",\"three\"]}"
}
}$index->insertDocument([
'title'=> 'title',
'data' => [
'tags' => [1,2,3]
]
],1);
$index->updateDocument([
'data' => [
'one', 'two', 'three'
]
],1);indexApi.insert({"table" : "products", "id" : 100, "doc" : {"title" : "title", "meta" : {"tags":[1,2,3]}}})
indexApi.update({"table" : "products", "id" : 100, "doc" : {"meta" : {"tags":['one','two','three']}}})await indexApi.insert({"table" : "products", "id" : 100, "doc" : {"title" : "title", "meta" : {"tags":[1,2,3]}}})
await indexApi.update({"table" : "products", "id" : 100, "doc" : {"meta" : {"tags":['one','two','three']}}})res = await indexApi.insert({"table" : "products", "id" : 100, "doc" : {"title" : "title", "meta" : {"tags":[1,2,3]}}});
res = await indexApi.update({"table" : "products", "id" : 100, "doc" : {"meta" : {"tags":['one','two','three']}}});InsertDocumentRequest newdoc = new InsertDocumentRequest();
doc = new HashMap<String,Object>(){{
put("title","title");
put("meta",
new HashMap<String,Object>(){{
put("tags",new int[]{1,2,3});
}});
}};
newdoc.index("products").id(100L).setDoc(doc);
indexApi.insert(newdoc);
updatedoc = new UpdateDocumentRequest();
doc = new HashMap<String,Object >(){{
put("meta",
new HashMap<String,Object>(){{
put("tags",new String[]{"one","two","three"});
}});
}};
updatedoc.index("products").id(100L).setDoc(doc);
indexApi.update(updatedoc);Dictionary<string, Object> meta = new Dictionary<string, Object>();
meta.Add("tags", new List<int> {1,2,3});
Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("title", "title");
doc.Add("meta", meta);
InsertDocumentRequest newdoc = new InsertDocumentRequest(index: "products", id: 100, doc: doc);
indexApi.Insert(newdoc);
meta = new Dictionary<string, Object>();
meta.Add("tags", new List<string> {"one","two","three"});
doc = new Dictionary<string, Object>();
doc.Add("meta", meta);
UpdateDocumentRequest updatedoc = new UpdateDocumentRequest(index: "products", id: 100, doc: doc);
indexApi.Update(updatedoc);let mut meta = HashMap::new();
meta.insert("tags".to_string(), serde_json::json!([1,2,3]));
let mut doc = HashMap::new();
doc.insert("title".to_string(), serde_json::json!("title"));
doc.insert("meta".to_string(), serde_json::json!(meta));
let insert_req = InsertDocumentRequest {
table: serde_json::json!("products"),
doc: serde_json::json!(doc),
id: serde_json::json!(100),
..Default::default(),
};
let insert_res = index_api.insert(insert_req).await;
meta = HashMap::new();
meta.insert("tags".to_string(), serde_json::json!(["one","two","three"]));
doc = HashMap::new();
doc.insert("meta".to_string(), serde_json::json!(meta));
let update_req = UpdateDocumentRequest {
table: serde_json::json!("products"),
doc: serde_json::json!(doc),
id: serde_json::json!(100),
..Default::default(),
};
let update_res = index_api.update(update_req).await;res = await indexApi.insert({
index: 'test',
id: 1,
doc: { content: 'Text 1', name: 'Doc 1', meta: { tags:[1,2,3] } }
})
res = await indexApi.update({ index: 'test', id: 1, doc: { meta: { tags:['one','two','three'] } } });metaField := map[string]interface{} {"tags": []int{1, 2, 3}}
insertDoc := map[string]interface{} {"name": "Doc 1", "meta": metaField}}
insertRequest := manticoreclient.NewInsertDocumentRequest("test", insertDoc)
insertRequest.SetId(1)
res, _, _ := apiClient.IndexAPI.Insert(context.Background()).InsertDocumentRequest(*insertRequest).Execute();
metaField = map[string]interface{} {"tags": []string{"one", "two", "three"}}
updateDoc := map[string]interface{} {"meta": metaField}
updateRequest := manticoreclient.NewUpdateDocumentRequest("test", updateDoc)
res, _, _ = apiClient.IndexAPI.Update(context.Background()).UpdateDocumentRequest(*updateRequest).Execute()Query OK, 1 row affected (0.00 sec)
Query OK, 1 row affected (0.00 sec){
"table":"products",
"updated":1
}Array(
[_index] => products
[_id] => 1
[created] => true
[result] => created
)
Array(
[_index] => products
[updated] => 1
){'created': True,
'found': None,
'id': 100,
'table': 'products',
'result': 'created'}
{'id': 100, 'table': 'products', 'result': 'updated', 'updated': None}{'created': True,
'found': None,
'id': 100,
'table': 'products',
'result': 'created'}
{'id': 100, 'table': 'products', 'result': 'updated', 'updated': None}{"table":"products","_id":100,"created":true,"result":"created"}
{"table":"products","_id":100,"result":"updated"}class SuccessResponse {
index: products
id: 100
created: true
result: created
found: null
}
class UpdateResponse {
index: products
updated: null
id: 100
result: updated
}class SuccessResponse {
index: products
id: 100
created: true
result: created
found: null
}
class UpdateResponse {
index: products
updated: null
id: 100
result: updated
}class SuccessResponse {
index: products
id: 100
created: true
result: created
found: null
}
class UpdateResponse {
index: products
updated: null
id: 100
result: updated
}{
"table":"test",
"_id":1,
"created":true,
"result":"created"
}
{
"table":"test",
"_id":1,
"result":"updated"
}{
"table":"test",
"_id":1,
"created":true,
"result":"created"
}
{
"table":"test",
"_id":1,
"result":"updated"
}При использовании репликации имя таблицы должно быть предварено cluster_name: (в SQL), чтобы обновления распространялись на все узлы в кластере. Для запросов через HTTP следует установить свойство cluster. Подробнее см. настройка репликации.
{
"cluster":"nodes4",
"table":"test",
"id":1,
"doc":
{
"gid" : 100,
"price" : 1000
}
}
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
update weekly:posts set enabled=0 where id=1;POST /update
{
"cluster":"weekly",
"table":"products",
"id":1,
"doc":
{
"enabled":0
}
}$index->setName('products')->setCluster('weekly');
$index->updateDocument(['enabled'=>0],1);indexApi.update({"cluster":"weekly", "table" : "products", "id" : 1, "doc" : {"enabled" : 0}})await indexApi.update({"cluster":"weekly", "table" : "products", "id" : 1, "doc" : {"enabled" : 0}})res = wait indexApi.update({"cluster":"weekly", "table" : "products", "id" : 1, "doc" : {"enabled" : 0}});updatedoc = new UpdateDocumentRequest();
doc = new HashMap<String,Object >(){{
put("enabled",0);
}};
updatedoc.index("products").cluster("weekly").id(1L).setDoc(doc);
indexApi.update(updatedoc);Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("enabled", 0);
UpdateDocumentRequest updatedoc = new UpdateDocumentRequest(index: "products", cluster: "weekly", id: 1, doc: doc);
indexApi.Update(updatedoc);let mut doc = HashMap::new();
doc.insert("enabled".to_string(), serde_json::json!(0));
let update_req = UpdateDocumentRequest {
table: serde_json::json!("products"),
cluster: serde_json::json!("weekly"),
doc: serde_json::json!(doc),
id: serde_json::json!(1),
};
let update_res = index_api.update(update_req).await;res = wait indexApi.update( {cluster: 'test_cluster', index : 'test', id : 1, doc : {name : 'Doc 11'}} );updateDoc = map[string]interface{} {"name":"Doc 11"}
updateRequest = manticoreclient.NewUpdateDocumentRequest("test", updateDoc)
updateRequest.SetCluster("test_cluster")
updateRequest.SetId(1)
res, _, _ = apiClient.IndexAPI.Update(context.Background()).UpdateDocumentRequest(*updateRequest).Execute()Вот синтаксис оператора SQL UPDATE:
UPDATE table SET col1 = newval1 [, ...] WHERE where_condition [OPTION opt_name = opt_value [, ...]] [FORCE|IGNORE INDEX(id)]
where_condition имеет тот же синтаксис, что и в операторе SELECT.
Наборы значений многозначных атрибутов должны быть указаны в виде списков, разделенных запятыми, в круглых скобках. Чтобы удалить все значения из многозначного атрибута, просто присвойте ему ().
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
UPDATE products SET tags1=(3,6,4) WHERE id=1;
UPDATE products SET tags1=() WHERE id=1;POST /update
{
"table":"products",
"_id":1,
"doc":
{
"tags1": []
}
}$index->updateDocument(['tags1'=>[]],1);indexApi.update({"table" : "products", "id" : 1, "doc" : {"tags1": []}})await indexApi.update({"table" : "products", "id" : 1, "doc" : {"tags1": []}})indexApi.update({"table" : "products", "id" : 1, "doc" : {"tags1": []}})updatedoc = new UpdateDocumentRequest();
doc = new HashMap<String,Object >(){{
put("tags1",new int[]{});
}};
updatedoc.index("products").id(1L).setDoc(doc);
indexApi.update(updatedoc);Dictionary<string, Object> doc = new Dictionary<string, Object>();
doc.Add("tags1", new List<int> {});
UpdateDocumentRequest updatedoc = new UpdateDocumentRequest(index: "products", id: 1, doc: doc);
indexApi.Update(updatedoc);let mut doc = HashMap::new();
doc.insert("tags1".to_string(), serde_json::json!([]));
let update_req = UpdateDocumentRequest {
table: serde_json::json!("products"),
doc: serde_json::json!(doc),
id: serde_json::json!(1),
..Default::default(),
};
let update_res = index_api.update(update_req).await;res = await indexApi.update({ index: 'test', id: 1, doc: { cat: 10 } });updateDoc = map[string]interface{} {"cat":10}
updateRequest = manticoreclient.NewUpdateDocumentRequest("test", updateDoc)
updateRequest.SetId(1)
res, _, _ = apiClient.IndexAPI.Update(context.Background()).UpdateDocumentRequest(*updateRequest).Execute()Query OK, 1 row affected (0.00 sec)
Query OK, 1 row affected (0.00 sec){
"table":"products",
"updated":1
}Array(
[_index] => products
[updated] => 1
){'id': 1, 'table': 'products', 'result': 'updated', 'updated': None}{'id': 1, 'table': 'products', 'result': 'updated', 'updated': None}{"table":"products","_id":1,"result":"updated"}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}class UpdateResponse {
index: products
updated: null
id: 1
result: updated
}{
"table":"test",
"_id":1,
"result":"updated"
}{
"table":"test",
"_id":1,
"result":"updated"
}Предложение OPTION — это специфичное для Manticore расширение, которое позволяет управлять рядом опций для каждого обновления. Синтаксис:
OPTION <optionname>=<value> [ , ... ]
Опции те же, что и для оператора SELECT. Конкретно для оператора UPDATE можно использовать следующие опции:
- 'ignore_nonexistent_columns' - Если установлено значение 1, это означает, что обновление будет молча игнорировать любые предупреждения о попытке обновить столбец, который не существует в текущей схеме таблицы. Значение по умолчанию — 0.
- 'strict' - Эта опция используется при частичных обновлениях JSON-атрибутов. По умолчанию (strict=1)
UPDATEприведет к ошибке, если запросUPDATEпытается выполнить обновление нечисловых свойств. При strict=0, если обновляются несколько свойств и некоторые из них не разрешены,UPDATEне приведет к ошибке и выполнит изменения только для разрешенных свойств (остальные будут проигнорированы). Если ни одно из измененийSETвUPDATEне разрешено, команда приведет к ошибке даже при strict=0.
В редких случаях встроенный анализатор запросов Manticore может некорректно понять запрос и определить, следует ли использовать таблицу по ID. Это может привести к плохой производительности для запросов вида UPDATE ... WHERE id = 123.
Информацию о том, как заставить оптимизатор использовать индекс docid, см. в разделе Подсказки оптимизатора запросов.
Обновления с использованием протокола HTTP JSON выполняются через конечную точку /update. Синтаксис аналогичен конечной точке /insert, но на этот раз свойство doc является обязательным.
Сервер ответит объектом JSON, указывающим, была ли операция успешной.
- JSON
POST /update
{
"table":"test",
"id":1,
"doc":
{
"gid" : 100,
"price" : 1000
}
}{
"table": "test",
"_id": 1,
"result": "updated"
}ID документа, который необходимо обновить, может быть установлен напрямую с помощью свойства id, как показано в предыдущем примере, или вы можете обновлять документы по запросу и применять обновление ко всем документам, соответствующим запросу:
- JSON
POST /update
{
"table":"test",
"doc":
{
"price" : 1000
},
"query":
{
"match": { "*": "apple" }
}
}{
"table":"products",
"updated":1
}Синтаксис запроса такой же, как в конечной точке /search. Обратите внимание, что нельзя указывать одновременно id и query.
FLUSH ATTRIBUTES
Команда FLUSH ATTRIBUTES гарантирует, что все обновления атрибутов в памяти во всех активных таблицах сбрасываются на диск. Она возвращает тег, идентифицирующий результирующее состояние на диске, которое представляет количество фактических сохранений атрибутов на диск с момента запуска сервера.
mysql> UPDATE testindex SET channel_id=1107025 WHERE id=1;
Query OK, 1 row affected (0.04 sec)
mysql> FLUSH ATTRIBUTES;
+------+
| tag |
+------+
| 1 |
+------+
1 row in set (0.19 sec)
Смотрите также настройку attr_flush_period.
Вы можете выполнить несколько операций обновления за один вызов, используя конечную точку /bulk. Эта конечная точка работает только с данными, у которых Content-Type установлен в application/x-ndjson. Данные должны быть отформатированы как JSON, разделенный символами новой строки (NDJSON). По сути, это означает, что каждая строка должна содержать ровно одно JSON-выражение и заканчиваться символом новой строки \n и, возможно, \r.
- JSON
POST /bulk
{ "update" : { "table" : "products", "id" : 1, "doc": { "price" : 10 } } }
{ "update" : { "table" : "products", "id" : 2, "doc": { "price" : 20 } } }{
"items":
[
{
"update":
{
"table":"products",
"_id":1,
"result":"updated"
}
},
{
"update":
{
"table":"products",
"_id":2,
"result":"updated"
}
}
],
"errors":false
}Конечная точка /bulk поддерживает вставки, замены и удаления. Каждое выражение начинается с типа действия (в данном случае update). Вот список поддерживаемых действий:
insert: Вставляет документ. Синтаксис такой же, как в конечной точке /insert.create: синоним дляinsertreplace: Заменяет документ. Синтаксис такой же, как в /replace.index: синоним дляreplaceupdate: Обновляет документ. Синтаксис такой же, как в /update.delete: Удаляет документ. Синтаксис такой же, как в конечной точке /delete endpoint.
Также поддерживаются обновления по запросу и удаления по запросу.
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
POST /bulk
{ "update" : { "table" : "products", "doc": { "coeff" : 1000 }, "query": { "range": { "price": { "gte": 1000 } } } } }
{ "update" : { "table" : "products", "doc": { "coeff" : 0 }, "query": { "range": { "price": { "lt": 1000 } } } } }$client->bulk([
['update'=>[
'table' => 'products',
'doc' => [
'coeff' => 100
],
'query' => [
'range' => ['price'=>['gte'=>1000]]
]
]
],
['update'=>[
'table' => 'products',
'doc' => [
'coeff' => 0
],
'query' => [
'range' => ['price'=>['lt'=>1000]]
]
]
]
]);docs = [ \
{ "update" : { "table" : "products", "doc": { "coeff" : 1000 }, "query": { "range": { "price": { "gte": 1000 } } } } }, \
{ "update" : { "table" : "products", "doc": { "coeff" : 0 }, "query": { "range": { "price": { "lt": 1000 } } } } } ]
indexApi.bulk('\n'.join(map(json.dumps,docs)))docs = [ \
{ "update" : { "table" : "products", "doc": { "coeff" : 1000 }, "query": { "range": { "price": { "gte": 1000 } } } } }, \
{ "update" : { "table" : "products", "doc": { "coeff" : 0 }, "query": { "range": { "price": { "lt": 1000 } } } } } ]
await indexApi.bulk('\n'.join(map(json.dumps,docs)))docs = [
{ "update" : { "table" : "products", "doc": { "coeff" : 1000 }, "query": { "range": { "price": { "gte": 1000 } } } } },
{ "update" : { "table" : "products", "doc": { "coeff" : 0 }, "query": { "range": { "price": { "lt": 1000 } } } } } ];
res = await indexApi.bulk(docs.map(e=>JSON.stringify(e)).join('\n'));String body = "{ \"update\" : { \"index\" : \"products\", \"doc\": { \"coeff\" : 1000 }, \"query\": { \"range\": { \"price\": { \"gte\": 1000 } } } }} "+"\n"+
"{ \"update\" : { \"index\" : \"products\", \"doc\": { \"coeff\" : 0 }, \"query\": { \"range\": { \"price\": { \"lt\": 1000 } } } } }"+"\n";
indexApi.bulk(body);string body = "{ \"update\" : { \"index\" : \"products\", \"doc\": { \"coeff\" : 1000 }, \"query\": { \"range\": { \"price\": { \"gte\": 1000 } } } }} "+"\n"+
"{ \"update\" : { \"index\" : \"products\", \"doc\": { \"coeff\" : 0 }, \"query\": { \"range\": { \"price\": { \"lt\": 1000 } } } } }"+"\n";
indexApi.Bulk(body);string body = r#"{ "update" : { "index" : "products", "doc": { "coeff" : 1000 }, "query": { "range": { "price": { "gte": 1000 } } } }}
{ "update" : { "index" : "products", "doc": { "coeff" : 0 }, "query": { "range": { "price": { "lt": 1000 } } } } }
"#;
index_api.bulk(body).await;updateDocs = [
{
update: {
index: 'test',
id: 1,
doc: { content: 'Text 11', cat: 1, name: 'Doc 11' },
},
},
{
update: {
index: 'test',
id: 2,
doc: { content: 'Text 22', cat: 9, name: 'Doc 22' },
},
},
];
res = await indexApi.bulk(
updateDocs.map((e) => JSON.stringify(e)).join("\n")
);body := "{\"update\": {\"index\": \"test\", \"id\": 1, \"doc\": {\"content\": \"Text 11\", \"name\": \"Doc 11\", \"cat\": 1 }}}" + "\n" +
"{\"update\": {\"index\": \"test\", \"id\": 2, \"doc\": {\"content\": \"Text 22\", \"name\": \"Doc 22\", \"cat\": 9 }}}" +"\n";
res, _, _ := apiClient.IndexAPI.Bulk(context.Background()).Body(body).Execute(){
"items":
[
{
"update":
{
"table":"products",
"updated":1
}
},
{
"update":
{
"table":"products",
"updated":3
}
}
],
"errors":false
}Array(
[items] => Array (
Array(
[update] => Array(
[_index] => products
[updated] => 1
)
)
Array(
[update] => Array(
[_index] => products
[updated] => 3
)
)
){'error': None,
'items': [{u'update': {u'table': u'products', u'updated': 1}},
{u'update': {u'table': u'products', u'updated': 3}}]}{'error': None,
'items': [{u'update': {u'table': u'products', u'updated': 1}},
{u'update': {u'table': u'products', u'updated': 3}}]}{"items":[{"update":{"table":"products","updated":1}},{"update":{"table":"products","updated":3}}],"errors":false}class BulkResponse {
items: [{update={_index=products, _id=1, created=false, result=updated, status=200}}, {update={_index=products, _id=2, created=false, result=updated, status=200}}]
error: null
additionalProperties: {errors=false}
}class BulkResponse {
items: [{update={_index=products, _id=1, created=false, result=updated, status=200}}, {update={_index=products, _id=2, created=false, result=updated, status=200}}]
error: null
additionalProperties: {errors=false}
}class BulkResponse {
items: [{update={_index=products, _id=1, created=false, result=updated, status=200}}, {update={_index=products, _id=2, created=false, result=updated, status=200}}]
error: null
additionalProperties: {errors=false}
}{
"items":
[
{
"update":
{
"table":"test",
"updated":1
}
},
{
"update":
{
"table":"test",
"updated":1
}
}
],
"errors":false
}{
"items":
[
{
"update":
{
"table":"test",
"updated":1
}
},
{
"update":
{
"table":"test",
"updated":1
}
}
],
"errors":false
}Имейте в виду, что массовая операция останавливается при первом запросе, который приводит к ошибке.
attr_update_reserve=size
attr_update_reserve — это настройка для каждой таблицы, которая определяет пространство, зарезервированное для обновлений атрибутов-больших объектов (blob). Эта настройка является необязательной, значение по умолчанию — 128k.
Когда обновляются атрибуты-большие объекты (MVA, строки, JSON), их длина может измениться. Если обновленная строка (или MVA, или JSON) короче старой, она перезаписывает старую в файле .spb. Однако, если обновленная строка длиннее, обновления записываются в конец файла .spb. Этот файл отображается в память, что означает, что изменение его размера может быть довольно медленным процессом, в зависимости от реализации операционной системой файлов, отображаемых в память.
Чтобы избежать частого изменения размера, вы можете указать дополнительное пространство, которое должно быть зарезервировано в конце файла .spb, с помощью этой опции.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
- CONFIG
create table products(title text, price float) attr_update_reserve = '1M'POST /cli -d "
create table products(title text, price float) attr_update_reserve = '1M'"$params = [
'body' => [
'settings' => [
'attr_update_reserve' => '1M'
],
'columns' => [
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
]
],
'table' => 'products'
];
$index = new \Manticoresearch\Index($client);
$index->create($params);utilsApi.sql('create table products(title text, price float) attr_update_reserve = \'1M\'')await utilsApi.sql('create table products(title text, price float) attr_update_reserve = \'1M\'')res = await utilsApi.sql('create table products(title text, price float) attr_update_reserve = \'1M\'');utilsApi.sql("create table products(title text, price float) attr_update_reserve = '1M'", true);utilsApi.Sql("create table products(title text, price float) attr_update_reserve = '1M'", true);utils_api.sql("create table products(title text, price float) attr_update_reserve = '1M'", Some(true)).await;utilsApi.sql("create table test(content text, name string, cat int) attr_update_reserve = '1M'");apiClient.UtilsAPI.Sql(context.Background()).Body("create table test(content text, name string, cat int) attr_update_reserve = '1M'").Execute()table products {
attr_update_reserve = 1M
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}attr_flush_period = 900 # persist updates to disk every 15 minutes
При обновлении атрибутов изменения сначала записываются в копию атрибутов в памяти. Эта настройка позволяет установить интервал между сбросом обновлений на диск. По умолчанию значение равно 0, что отключает периодический сброс, но сброс все равно будет происходить при нормальном завершении работы.
Удаление документов поддерживается только в режиме реального времени (RT) для следующих типов таблиц:
- Реального времени (Real-time) таблицы
- Перколяционные (Percolate) таблицы
- Распределенные таблицы, которые содержат только RT-таблицы в качестве локальных или удаленных агентов.
Вы можете удалять существующие документы из таблицы либо по их ID, либо по определенным условиям.
Также доступно массовое удаление для удаления нескольких документов.
Удаление документов может быть выполнено как через SQL, так и через JSON интерфейсы.
Для SQL успешная операция вернет количество удаленных строк.
Для JSON используется конечная точка json/delete. Сервер ответит JSON-объектом, указывающим, была ли операция успешной, и количество удаленных строк.
Рекомендуется использовать очистку таблицы (truncation) вместо удаления для удаления всех документов из таблицы, так как это гораздо более быстрая операция.
В этом примере мы удаляем все документы, соответствующие полнотекстовому запросу test document, из таблицы с именем test:
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
mysql> SELECT * FROM TEST;
+------+------+-------------+------+
| id | gid | mva1 | mva2 |
+------+------+-------------+------+
| 100 | 1000 | 100,201 | 100 |
| 101 | 1001 | 101,202 | 101 |
| 102 | 1002 | 102,203 | 102 |
| 103 | 1003 | 103,204 | 103 |
| 104 | 1004 | 104,204,205 | 104 |
| 105 | 1005 | 105,206 | 105 |
| 106 | 1006 | 106,207 | 106 |
| 107 | 1007 | 107,208 | 107 |
+------+------+-------------+------+
8 rows in set (0.00 sec)
mysql> DELETE FROM TEST WHERE MATCH ('test document');
Query OK, 2 rows affected (0.00 sec)
mysql> SELECT * FROM TEST;
+------+------+-------------+------+
| id | gid | mva1 | mva2 |
+------+------+-------------+------+
| 100 | 1000 | 100,201 | 100 |
| 101 | 1001 | 101,202 | 101 |
| 102 | 1002 | 102,203 | 102 |
| 103 | 1003 | 103,204 | 103 |
| 104 | 1004 | 104,204,205 | 104 |
| 105 | 1005 | 105,206 | 105 |
+------+------+-------------+------+
6 rows in set (0.00 sec)POST /delete -d '
{
"table":"test",
"query":
{
"match": { "*": "test document" }
}
}'queryдля JSON содержит условие для полнотекстового поиска; он имеет тот же синтаксис, что и в JSON/update.
$index->deleteDocuments(new MatchPhrase('test document','*'));indexApi.delete({"table" : "test", "query": { "match": { "*": "test document" }}})indexApi.delete({"table" : "test", "query": { "match": { "*": "test document" }}})res = await indexApi.delete({"table" : "test", "query": { "match": { "*": "test document" }}});DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
query = new HashMap<String,Object>();
query.put("match",new HashMap<String,Object>(){{
put("*","test document");
}});
deleteRequest.index("test").setQuery(query);
indexApi.delete(deleteRequest);Dictionary<string, Object> match = new Dictionary<string, Object>();
match.Add("*", "test document");
Dictionary<string, Object> query = new Dictionary<string, Object>();
query.Add("match", match);
DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest(index: "test", query: query);
indexApi.Delete(deleteRequest);let match_expr = HashMap::new();
match_expr.insert("*".to_string(), serde_json::json!("test document"));
let query = SearchQuery {
match: Some(serde_json::json!(match_expr).into()),
..Default::default()
};
let delete_req = DeleteDocumentRequest::new("test".to_string());
index_api.delete(delete_req).await;res = await indexApi.delete({
index: 'test',
query: { match: { '*': 'test document' } },
});deleteRequest := manticoresearch.NewDeleteDocumentRequest("test")
matchExpr := map[string]interface{} {"*": "test document"}
deleteQuery := map[string]interface{} {"match": matchExpr }
deleteRequest.SetQuery(deleteQuery){
"table":"test",
"deleted":2,
}Array(
[_index] => test
[deleted] => 2
){'deleted': 5, 'id': None, 'table': 'test', 'result': None}{'deleted': 5, 'id': None, 'table': 'test', 'result': None}{"table":"test","deleted":5}class DeleteResponse {
index: test
deleted: 5
id: null
result: null
}class DeleteResponse {
index: test
deleted: 5
id: null
result: null
}class DeleteResponse {
index: test
deleted: 5
id: null
result: null
}{"table":"test","deleted":5}{"table":"test","deleted":5}Здесь - удаление документа с id, равным 1, из таблицы с именем test:
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
mysql> DELETE FROM TEST WHERE id=1;
Query OK, 1 rows affected (0.00 sec)POST /delete -d '
{
"table": "test",
"id": 1
}'idдля JSON - этоidстроки, которую следует удалить.
$index->deleteDocument(1);indexApi.delete({"table" : "test", "id" : 1})indexApi.delete({"table" : "test", "id" : 1})res = await indexApi.delete({"table" : "test", "id" : 1});DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
deleteRequest.index("test").setId(1L);
indexApi.delete(deleteRequest);DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest(index: "test", id: 1);
indexApi.Delete(deleteRequest);let delete_req = DeleteDocumentRequest {
table: "test".to_string(),
id: serde_json::json!(1),
..Default::default(),
};
index_api.delete(delete_req).await;res = await indexApi.delete({ index: 'test', id: 1 });deleteRequest := manticoresearch.NewDeleteDocumentRequest("test")
deleteRequest.SetId(1){
"table": "test",
"_id": 1,
"found": true,
"result": "deleted"
}Array(
[_index] => test
[_id] => 1
[found] => true
[result] => deleted
){'deleted': None, 'id': 1, 'table': 'test', 'result': 'deleted'}{'deleted': None, 'id': 1, 'table': 'test', 'result': 'deleted'}{"table":"test","_id":1,"result":"deleted"}class DeleteResponse {
index: test
_id: 1
result: deleted
}class DeleteResponse {
index: test
_id: 1
result: deleted
}class DeleteResponse {
index: test
_id: 1
result: deleted
}{"table":"test","_id":1,"result":"deleted"}{"table":"test","_id":1,"result":"deleted"}Здесь удаляются документы с id, соответствующими значениям из таблицы с именем test:
Обратите внимание, что формы удаления с id=N или id IN (X,Y) являются самыми быстрыми, так как они удаляют документы без выполнения поиска.
Также обратите внимание, что ответ содержит только id первого удаленного документа в соответствующем поле _id.
- SQL
- JSON
- PHP
DELETE FROM TEST WHERE id IN (1,2);POST /delete -d '
{
"table":"test",
"id": [1,2]
}'$index->deleteDocumentsByIds([1,2]);Query OK, 2 rows affected (0.00 sec) {
"table":"test",
"_id":1,
"found":true,
"result":"deleted"
}Array(
[_index] => test
[_id] => 1
[found] => true
[result] => deleted
)Manticore SQL позволяет использовать сложные условия для оператора DELETE.
Например, здесь мы удаляем документы, которые соответствуют полнотекстовому запросу test document и имеют атрибут mva1 со значением больше 206 или значения mva1 100 или 103 из таблицы с именем test:
- SQL
DELETE FROM TEST WHERE MATCH ('test document') AND ( mva1>206 or mva1 in (100, 103) );
SELECT * FROM TEST;Query OK, 4 rows affected (0.00 sec)
+------+------+-------------+------+
| id | gid | mva1 | mva2 |
+------+------+-------------+------+
| 101 | 1001 | 101,202 | 101 |
| 102 | 1002 | 102,203 | 102 |
| 104 | 1004 | 104,204,205 | 104 |
| 105 | 1005 | 105,206 | 105 |
+------+------+-------------+------+
6 rows in set (0.00 sec)Вот пример удаления документов в таблице test кластера cluster. Обратите внимание, что мы должны указать свойство имени кластера вместе со свойством таблицы, чтобы удалить строку из таблицы внутри репликационного кластера:
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
delete from cluster:test where id=100;POST /delete -d '
{
"cluster": "cluster",
"table": "test",
"id": 100
}'clusterдля JSON - это имя репликационного кластера. который содержит нужную таблицу
$index->setCluster('cluster');
$index->deleteDocument(100);indexApi.delete({"cluster":"cluster","table" : "test", "id" : 1})indexApi.delete({"cluster":"cluster","table" : "test", "id" : 1})indexApi.delete({"cluster":"cluster_1","table" : "test", "id" : 1})DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
deleteRequest.cluster("cluster").index("test").setId(1L);
indexApi.delete(deleteRequest);DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest(index: "test", cluster: "cluster", id: 1);
indexApi.Delete(deleteRequest);let delete_req = DeleteDocumentRequest {
table: "test".to_string(),
cluster: "cluster".to_string(),
id: serde_json::json!(1),
..Default::default(),
};
index_api.delete(delete_req).await;res = await indexApi.delete({ cluster: 'cluster_1', index: 'test', id: 1 });deleteRequest := manticoresearch.NewDeleteDocumentRequest("test")
deleteRequest.SetCluster("cluster_1")
deleteRequest.SetId(1)Array(
[_index] => test
[_id] => 100
[found] => true
[result] => deleted
){'deleted': None, 'id': 1, 'table': 'test', 'result': 'deleted'}{'deleted': None, 'id': 1, 'table': 'test', 'result': 'deleted'}{"table":"test","_id":1,"result":"deleted"}class DeleteResponse {
index: test
_id: 1
result: deleted
}class DeleteResponse {
index: test
_id: 1
result: deleted
}class DeleteResponse {
index: test
_id: 1
result: deleted
}{"table":"test","_id":1,"result":"deleted"}{"table":"test","_id":1,"result":"deleted"}Вы также можете выполнить несколько операций удаления за один вызов, используя конечную точку /bulk. Эта конечная точка работает только с данными, у которых установлен Content-Type в значение application/x-ndjson. Данные должны быть отформатированы как JSON, разделенный символами новой строки (NDJSON). По сути, это означает, что каждая строка должна содержать ровно одно JSON-выражение и заканчиваться символом новой строки \n и, возможно, \r.
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- TypeScript
- Go
POST /bulk
{ "delete" : { "table" : "test", "id" : 1 } }
{ "delete" : { "table" : "test", "query": { "equals": { "int_data" : 20 } } } }$client->bulk([
['delete' => [
'table' => 'test',
'id' => 1
]
],
['delete'=>[
'table' => 'test',
'query' => [
'equals' => ['int_data' => 20]
]
]
]
]);docs = [ \
{ "delete" : { "table" : "test", "id": 1 } }, \
{ "delete" : { "table" : "test", "query": { "equals": { "int_data": 20 } } } } ]
indexApi.bulk('\n'.join(map(json.dumps,docs)))docs = [ \
{ "delete" : { "table" : "test", "id": 1 } }, \
{ "delete" : { "table" : "test", "query": { "equals": { "int_data": 20 } } } } ]
indexApi.bulk('\n'.join(map(json.dumps,docs)))docs = [
{ "delete" : { "table" : "test", "id": 1 } },
{ "delete" : { "table" : "test", "query": { "equals": { "int_data": 20 } } } } ];
res = await indexApi.bulk(docs.map(e=>JSON.stringify(e)).join('\n'));String body = "{ "delete" : { "table" : "test", "id": 1 } } "+"\n"+
"{ "delete" : { "table" : "test", "query": { "equals": { "int_data": 20 } } } }"+"\n";
indexApi.bulk(body);string body = "{ "delete" : { "table" : "test", "id": 1 } } "+"\n"+
"{ "delete" : { "table" : "test", "query": { "equals": { "int_data": 20 } } } }"+"\n";
indexApi.Bulk(body);let bulk_body = r#"{ "delete" : { "table" : "test", "id": 1 } }
{ "delete" : { "table" : "test", "query": { "equals": { "int_data": 20 } } } }"
"#;
index_api.bulk(bulk_body).await;docs = [
{ "delete" : { "table" : "test", "id": 1 } },
{ "delete" : { "table" : "test", "query": { "equals": { "int_data": 20 } } } }
];
body = await indexApi.bulk(
docs.map((e) => JSON.stringify(e)).join("\n")
);
res = await indexApi.bulk(body);docs = []string {
`{ "delete" : { "table" : "test", "id": 1 } }`,
`{ "delete" : { "table" : "test", "query": { "equals": { "int_data": 20 } } } }`
]
body = strings.Join(docs, "\n")
resp, httpRes, err := manticoreclient.IndexAPI.Bulk(context.Background()).Body(body).Execute(){
"items":
[
{
"bulk":
{
"table":"test",
"_id":0,
"created":0,
"deleted":2,
"updated":0,
"result":"created",
"status":201
}
}
],
"errors":false
}Array(
[items] => Array
(
[0] => Array
(
[bulk] => Array
(
[_index] => test
[_id] => 0
[created] => 0
[deleted] => 2
[updated] => 0
[result] => created
[status] => 201
)
)
)
[current_line] => 3
[skipped_lines] => 0
[errors] =>
[error] =>
){
'error': None,
'items': [{u'delete': {u'table': test', u'deleted': 2}}]
}{
'error': None,
'items': [{u'delete': {u'table': test', u'deleted': 2}}]
}{"items":[{"delete":{"table":"test","deleted":2}}],"errors":false}class BulkResponse {
items: [{delete={_index=test, _id=0, created=false, deleted=2, result=created, status=200}}]
error: null
additionalProperties: {errors=false}
}class BulkResponse {
items: [{replace={_index=test, _id=0, created=false, deleted=2, result=created, status=200}}]
error: null
additionalProperties: {errors=false}
}class BulkResponse {
items: [{replace={_index=test, _id=0, created=false, deleted=2, result=created, status=200}}]
error: null
additionalProperties: {errors=false}
}{"items":[{"delete":{"table":"test","deleted":2}}],"errors":false}{"items":[{"delete":{"table":"test","deleted":2}}],"errors":false}Manticore поддерживает базовые транзакции для удаления и вставки данных в реальном времени и в percolate таблицы, за исключением случаев, когда попытка записи производится в распределенную таблицу, которая включает таблицу реального времени или percolate таблицу. Каждое изменение таблицы сначала сохраняется во внутреннем наборе изменений, а затем фактически фиксируется в таблице. По умолчанию каждая команда оборачивается в отдельную автоматическую транзакцию, делая это прозрачным: вы просто 'вставляете' что-то и можете видеть результат вставки после ее завершения, не беспокоясь о транзакциях. Однако это поведение можно явно контролировать, начиная и фиксируя транзакции вручную.
Транзакции поддерживаются для следующих команд:
Транзакции не поддерживаются для:
- UPDATE (который отличается от REPLACE, так как выполняет обновление атрибутов на месте)
- ALTER - для обновления схемы таблицы
- TRUNCATE - для очистки таблицы реального времени
- ATTACH - для присоединения обычной таблицы к таблице реального времени
- CREATE - для создания таблицы
- DROP - для удаления таблицы
Обратите внимание, что транзакции в Manticore не стремятся обеспечить изоляцию. Цель транзакций в Manticore - позволить вам накапливать несколько записей и выполнять их все сразу при фиксации или откатывать их все при необходимости. Транзакции интегрированы с бинарным логом для обеспечения долговечности и согласованности.
SET AUTOCOMMIT = {0 | 1}
SET AUTOCOMMIT управляет режимом автозавершения в активной сессии. По умолчанию AUTOCOMMIT установлен в 1. При настройках по умолчанию вам не нужно беспокоиться о транзакциях, так как каждое выражение, вносящее изменения в любую таблицу, неявно оборачивается в отдельную транзакцию. Установка значения 0 позволяет управлять транзакциями вручную, что означает, что они не будут видны до тех пор, пока вы явно их не зафиксируете.
Транзакции ограничены одной таблицей реального времени или percolate таблицей, а также ограничены по размеру. Они атомарны, согласованы, чрезмерно изолированы и долговечны. Чрезмерно изолированы означает, что изменения невидимы не только для параллельных транзакций, но даже для самой текущей сессии.
START TRANSACTION | BEGIN
COMMIT
ROLLBACK
Оператор BEGIN (или его алиас START TRANSACTION) принудительно фиксирует любую ожидающую транзакцию, если она есть, и начинает новую.
Оператор COMMIT фиксирует текущую транзакцию, делая все ее изменения постоянными.
Оператор ROLLBACK откатывает текущую транзакцию, отменяя все ее изменения.
При использовании одной из конечных точек JSON /bulk ( пакетная вставка, пакетная замена, пакетное удаление ), вы можете принудительно зафиксировать пакет документов, добавив пустую строку после них.
insert into indexrt (id, content, title, channel_id, published) values (1, 'aa', 'blabla', 1, 10);
Query OK, 1 rows affected (0.00 sec)
select * from indexrt where id=1;
+------+------------+-----------+--------+
| id | channel_id | published | title |
+------+------------+-----------+--------+
| 1 | 1 | 10 | blabla |
+------+------------+-----------+--------+
1 row in set (0.00 sec)
Вставленное значение сразу становится видимым в следующем операторе 'select'.
set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
insert into indexrt (id, content, title, channel_id, published) values (3, 'aa', 'bb', 1, 1);
Query OK, 1 row affected (0.00 sec)
insert into indexrt (id, content, title, channel_id, published) values (4, 'aa', 'bb', 1, 1);
Query OK, 1 row affected (0.00 sec)
select * from indexrt where id=3;
Empty set (0.01 sec)
select * from indexrt where id=4;
Empty set (0.00 sec)
В этом случае изменения НЕ фиксируются автоматически. В результате вставки не видны, даже в той же сессии, поскольку они не были зафиксированы. Также, несмотря на отсутствие оператора BEGIN, транзакция неявно начинается.
Чтобы изменения стали видимыми, необходимо зафиксировать транзакцию:
commit;
Query OK, 0 rows affected (0.00 sec)
select * from indexrt where id=4;
+------+------------+-----------+-------+
| id | channel_id | published | title |
+------+------------+-----------+-------+
| 4 | 1 | 1 | bb |
+------+------------+-----------+-------+
1 row in set (0.00 sec)
select * from indexrt where id=3;
+------+------------+-----------+-------+
| id | channel_id | published | title |
+------+------------+-----------+-------+
| 3 | 1 | 1 | bb |
+------+------------+-----------+-------+
1 row in set (0.00 sec)
После оператора commit вставки становятся видимыми в таблице.
Используя BEGIN и COMMIT, вы можете явно определить границы транзакции, поэтому в этом случае не нужно беспокоиться об автозавершении.
begin;
Query OK, 0 rows affected (0.00 sec)
insert into indexrt (id, content, title, channel_id, published) values (2, 'aa', 'bb', 1, 1);
Query OK, 1 row affected (0.00 sec)
select * from indexrt where id=2;
Empty set (0.01 sec)
commit;
Query OK, 0 rows affected (0.01 sec)
select * from indexrt where id=2;
+------+------------+-----------+-------+
| id | channel_id | published | title |
+------+------------+-----------+-------+
| 2 | 1 | 1 | bb |
+------+------------+-----------+-------+
1 row in set (0.01 sec)