Deleting documents is only supported for the following table types:
- Real-time tables,
- Percolate tables,
- Distributed tables that only contain RT tables a local or remote agents.
You can delete existing documents from a table based on either their ID or certain conditions.
Deletion of documents can be accomplished via both SQL and HTTP interfaces.
For SQL, the response for a successful operation will indicate the number of rows deleted.
For HTTP, the json/delete
endpoint is used. The server will respond with a JSON object indicating whether the operation was successful and the number of rows deleted.
It is recommended to use table truncation instead of deletion to delete all documents from a table, as it is a much faster operation.
- SQL
- JSON
DELETE FROM table WHERE where_condition
table
is a name of the table from which the row should be deleted.where_condition
for SQL has the same syntax as in the SELECT statement.
POST /delete -d '
{
"index": "test",
"id": 1
}'
POST /delete -d '
{
"index": "test",
"query":
{
"match": { "*": "apple" }
}
}'
id
for JSON is the rowid
which should be deleted.query
for JSON is the full-text condition and has the same syntax as in the JSON/update.cluster
for JSON is cluster name property and should be set along withtable
property to delete a row from a table which is inside a replication cluster.
In this example we are deleting all documents that match full-text query dummy
from table named test
:
- SQL
- JSON
- PHP
- Python
- javascript
- Java
- C#
SELECT * FROM TEST;
DELETE FROM TEST WHERE MATCH ('dummy');
SELECT * FROM TEST;
POST /delete -d '
{
"index":"test",
"query":
{
"match": { "*": "dummy" }
}
}'
$index->deleteDocuments(new Match('dummy','*'));
indexApi.delete({"index" : "products", "query": { "match": { "*": "dummy" }}})
res = await indexApi.delete({"index" : "products", "query": { "match": { "*": "dummy" }}});
DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
query = new HashMap<String,Object>();
query.put("match",new HashMap<String,Object>(){{
put("*","dummy");
}});
deleteRequest.index("products").setQuery(query);
indexApi.delete(deleteRequest);
Dictionary<string, Object> match = new Dictionary<string, Object>();
match.Add("*", "dummy");
Dictionary<string, Object> query = new Dictionary<string, Object>();
query.Add("match", match);
DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest(index: "products", query: query);
indexApi.Delete(deleteRequest);
+------+------+-------------+------+
| 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)
Query OK, 2 rows affected (0.00 sec)
+------+------+-------------+------+
| 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)
{
"_index":"test",
"deleted":2,
}
Array(
[_index] => test
[deleted] => 2
)
{'deleted': 2, 'id': None, 'index': 'products', 'result': None}
{"_index":"products","deleted":2}
class DeleteResponse {
index: products
deleted: 2
id: null
result: null
}
class DeleteResponse {
index: products
deleted: 2
id: null
result: null
}
Here - deleting a document with id
100 from table named test
:
- SQL
- JSON
- PHP
- Python
- javascript
- Java
- C#
DELETE FROM TEST WHERE id=100;
SELECT * FROM TEST;
POST /delete -d '
{
"index":"test",
"id": 100
}'
$index->deleteDocument(100);
indexApi.delete({"index" : "products", "id" : 1})
res = await indexApi.delete({"index" : "products", "id" : 1});
DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
deleteRequest.index("products").setId(1L);
indexApi.delete(deleteRequest);
DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest(index: "products", id: 1);
indexApi.Delete(deleteRequest);
Query OK, 1 rows affected (0.00 sec)
+------+------+-------------+------+
| id | gid | mva1 | mva2 |
+------+------+-------------+------+
| 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 |
+------+------+-------------+------+
5 rows in set (0.00 sec)
{
"_index":"test",
"_id":100,
"found":true,
"result":"deleted"
}
Array(
[_index] => test
[_id] => 100
[found] => true
[result] => deleted
)
{'deleted': None, 'id': 1, 'index': 'products', 'result': 'deleted'}
{"_index":"products","_id":1,"result":"deleted"}
class DeleteResponse {
index: products
_id: 1
result: deleted
}
class DeleteResponse {
index: products
_id: 1
result: deleted
}
Manticore SQL allows to use complex conditions for the DELETE
statement.
For example here we are deleting documents that match full-text query dummy
and have attribute mva1
with a value greater than 206 or mva1
values 100 or 103 from table named test
:
- SQL
DELETE FROM TEST WHERE MATCH ('dummy') 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)
Here is an example of deleting documents in cluster cluster
's table test
:
- SQL
- JSON
- PHP
- Python
- javascript
- Java
- C#
delete from cluster:test where id=100;
POST /delete -d '
{
"cluster":"cluster",
"index":"test",
"id": 100
}'
$index->setCluster('cluster');
$index->deleteDocument(100);
indexApi.delete({"cluster":"cluster","index" : "products", "id" : 100})
indexApi.delete({"cluster":"cluster","index" : "products", "id" : 100})
DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest();
deleteRequest.cluster("cluster").index("products").setId(100L);
indexApi.delete(deleteRequest);
DeleteDocumentRequest deleteRequest = new DeleteDocumentRequest(index: "products", cluster: "cluster", id: 100);
indexApi.Delete(deleteRequest);
Array(
[_index] => test
[_id] => 100
[found] => true
[result] => deleted
)
{'deleted': None, 'id': 100, 'index': 'products', 'result': 'deleted'}
{"_index":"products","_id":100,"result":"deleted"}
class DeleteResponse {
index: products
_id: 100
result: deleted
}
class DeleteResponse {
index: products
_id: 100
result: deleted
}
You can also perform multiple delete operations in a single call using the /bulk
endpoint. This endpoint only works with data that has Content-Type
set to application/x-ndjson
. The data should be formatted as newline-delimited JSON (NDJSON). Essentially, this means that each line should contain exactly one JSON statement and end with a newline \n
and, possibly, a \r
.
- JSON
POST /bulk
{ "update" : { "delete" : "products", "id" : 1 } }
{ "update" : { "delete" : "products", "id" : 2, "query": { "equals": { "price" : 20 } } } }
{
"items":
[
{
"bulk":
{
"_index":"products",
"_id":0,
"created":0,
"deleted":2,
"updated":0,
"result":"created",
"status":201
}
}
],
"errors":false
}
Manticore supports basic transactions for deleting and inserting data into real-time and percolate tables. Each change to a table is first saved in an internal changeset and then actually committed to the table. By default, each command is wrapped in an individual automatic transaction, making it transparent: you simply 'insert' something and can see the inserted result after it completes, without worrying about transactions. However, this behavior can be explicitly managed by starting and committing transactions manually.
Transactions are supported for the following commands:
Transactions are not supported for:
- UPDATE (which is different from REPLACE, as it performs an in-place attribute update)
- ALTER - for updating table schema
- TRUNCATE - for emptying a real-time table
- ATTACH - for attaching a plain table to a real-time table
- CREATE - for creating a table
- DROP - for deleting a table
Please note that transactions in Manticore do not aim to provide isolation. The purpose of transactions in Manticore is to allow you to accumulate multiple writes and execute them all at once upon commit, or to roll them all back if necessary. Transactions are integrated with binary log for durability and consistency.
SET AUTOCOMMIT = {0 | 1}
SET AUTOCOMMIT
controls the autocommit mode in the active session. AUTOCOMMIT
is set to 1 by default. With the default setting, you don't have to worry about transactions, as every statement that makes any changes to any table is implicitly wrapped in a separate transaction. Setting it to 0 allows you to manage transactions manually, meaning they will not be visible until you explicitly commit them.
Transactions are limited to a single real-time or percolate table and are also limited in size. They are atomic, consistent, overly isolated, and durable. Overly isolated means that the changes are not only invisible to concurrent transactions but even to the current session itself.
START TRANSACTION | BEGIN
COMMIT
ROLLBACK
The BEGIN
statement (or its START TRANSACTION
alias) forcibly commits any pending transaction, if present, and starts a new one.
The COMMIT
statement commits the current transaction, making all its changes permanent.
The ROLLBACK
statement rolls back the current transaction, canceling all its changes.
When using the /bulk JSON endpoint, you can force a batch of documents to be committed by adding an empty line after them.
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)
The inserted value is immediately visible in the following 'select' statement.
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)
In this case, changes are NOT automatically committed. As a result, the insertions are not visible, even in the same session, since they have not been committed. Also, despite the absence of a BEGIN
statement, a transaction is implicitly started.
To make the changes visible, you need to commit the transaction:
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)
After the commit statement, the insertions are visible in the table.
By using BEGIN
and COMMIT
, you can define the bounds of a transaction explicitly, so there's no need to worry about autocommit in this case.
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)
✔ Searching
Searching is a core feature of Manticore Search. You can:
- Perform full-text search and implement search result highlighting
- Apply non-full-text filtering
- Use expressions for filtering
- Utilize various search options
- Employ multi-queries and sub-selects
- Conduct aggregations and faceting of search results
- And much more
SQL:
SELECT ... [OPTION <optionname>=<value> [ , ... ]]
HTTP:
POST /search
{
"index" : "index_name",
"options":
{
...
}
}