In a percolate table documents that are percolate query rules are stored and must follow the exact schema of four fields:
field | type | description |
---|---|---|
id | bigint | PQ rule identifier (if omitted, it will be assigned automatically) |
query | string | Full-text query (can be empty) compatible with the percolate table |
filters | string | Additional filters by non-full-text fields (can be empty) compatible with the percolate table |
tags | string | A string with one or many comma-separated tags, which may be used to selectively show/delete saved queries |
Any other field names are not supported and will trigger an error.
Warning: Inserting/replacing JSON-formatted PQ rules via SQL will not work. In other words, the JSON-specific operators (match
etc) will be considered just parts of the rule's text that should match with documents. If you prefer JSON syntax, use the HTTP endpoint instead of INSERT
/REPLACE
.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- Javascript
- Java
- C#
- Rust
INSERT INTO pq(id, query, filters) VALUES (1, '@title shoes', 'price > 5');
INSERT INTO pq(id, query, tags) VALUES (2, '@title bag', 'Louis Vuitton');
SELECT * FROM pq;
There are two ways you can add a percolate query into a percolate table:
-
Query in JSON /search compatible format, described at json/search
PUT /pq/pq_table/doc/1 { "query": { "match": { "title": "shoes" }, "range": { "price": { "gt": 5 } } }, "tags": ["Loius Vuitton"] }
-
Query in SQL format, described at search query syntax
PUT /pq/pq_table/doc/2 { "query": { "ql": "@title shoes" }, "filters": "price > 5", "tags": ["Loius Vuitton"] }
$newstoredquery = [
'table' => 'test_pq',
'body' => [
'query' => [
'match' => [
'title' => 'shoes'
]
],
'range' => [
'price' => [
'gt' => 5
]
]
],
'tags' => ['Loius Vuitton']
];
$client->pq()->doc($newstoredquery);
newstoredquery ={"table" : "test_pq", "id" : 2, "doc" : {"query": {"ql": "@title shoes"},"filters": "price > 5","tags": ["Loius Vuitton"]}}
indexApi.insert(newstoredquery)
newstoredquery ={"table" : "test_pq", "id" : 2, "doc" : {"query": {"ql": "@title shoes"},"filters": "price > 5","tags": ["Loius Vuitton"]}}
await indexApi.insert(newstoredquery)
newstoredquery ={"table" : "test_pq", "id" : 2, "doc" : {"query": {"ql": "@title shoes"},"filters": "price > 5","tags": ["Loius Vuitton"]}};
indexApi.insert(newstoredquery);
newstoredquery = new HashMap<String,Object>(){{
put("query",new HashMap<String,Object >(){{
put("q1","@title shoes");
put("filters","price>5");
put("tags",new String[] {"Loius Vuitton"});
}});
}};
newdoc.index("test_pq").id(2L).setDoc(doc);
indexApi.insert(newdoc);
Dictionary<string, Object> query = new Dictionary<string, Object>();
query.Add("q1", "@title shoes");
query.Add("filters", "price>5");
query.Add("tags", new List<string> {"Loius Vuitton"});
Dictionary<string, Object> newstoredquery = new Dictionary<string, Object>();
newstoredquery.Add("query", query);
InsertDocumentRequest newdoc = new InsertDocumentRequest(index: "test_pq", id: 2, doc: doc);
indexApi.Insert(newdoc);
let mut pq_doc = HashMap::new();
pq_doc.insert("q1".to_string(), serde_json::json!("@title shoes"));
pq_doc.insert("filters".to_string(), serde_json::json!("price>5"));
pq_doc.insert("tags".to_string(), serde_json::json!(["Louis Vitton"]));
let mut doc = HashMap::new();
pq_doc.insert("query".to_string(), serde_json::json!(pq_doc));
let insert_req = InsertDocumentRequest::new("test_pq".to_string(), serde_json::json!(doc));
let insert_res = index_api.insert(insert_req).await;
+------+--------------+---------------+---------+
| id | query | tags | filters |
+------+--------------+---------------+---------+
| 1 | @title shoes | | price>5 |
| 2 | @title bag | Louis Vuitton | |
+------+--------------+---------------+---------+
If you don't specify an ID, it will be assigned automatically. You can read more about auto-ID here.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- Javascript
- Java
- C#
- Rust
INSERT INTO pq(query, filters) VALUES ('wristband', 'price > 5');
SELECT * FROM pq;
PUT /pq/pq_table/doc
{
"query": {
"match": {
"title": "shoes"
},
"range": {
"price": {
"gt": 5
}
}
},
"tags": ["Loius Vuitton"]
}
PUT /pq/pq_table/doc
{
"query": {
"ql": "@title shoes"
},
"filters": "price > 5",
"tags": ["Loius Vuitton"]
}
$newstoredquery = [
'table' => 'pq_table',
'body' => [
'query' => [
'match' => [
'title' => 'shoes'
]
],
'range' => [
'price' => [
'gt' => 5
]
]
],
'tags' => ['Loius Vuitton']
];
$client->pq()->doc($newstoredquery);
indexApi = api = manticoresearch.IndexApi(client)
newstoredquery ={"table" : "test_pq", "doc" : {"query": {"ql": "@title shoes"},"filters": "price > 5","tags": ["Loius Vuitton"]}}
indexApi.insert(store_query)
indexApi = api = manticoresearch.IndexApi(client)
newstoredquery ={"table" : "test_pq", "doc" : {"query": {"ql": "@title shoes"},"filters": "price > 5","tags": ["Loius Vuitton"]}}
await indexApi.insert(store_query)
newstoredquery ={"table" : "test_pq", "doc" : {"query": {"ql": "@title shoes"},"filters": "price > 5","tags": ["Loius Vuitton"]}};
res = await indexApi.insert(store_query);
newstoredquery = new HashMap<String,Object>(){{
put("query",new HashMap<String,Object >(){{
put("q1","@title shoes");
put("filters","price>5");
put("tags",new String[] {"Loius Vuitton"});
}});
}};
newdoc.index("test_pq").setDoc(doc);
indexApi.insert(newdoc);
Dictionary<string, Object> query = new Dictionary<string, Object>();
query.Add("q1", "@title shoes");
query.Add("filters", "price>5");
query.Add("tags", new List<string> {"Loius Vuitton"});
Dictionary<string, Object> newstoredquery = new Dictionary<string, Object>();
newstoredquery.Add("query", query);
InsertDocumentRequest newdoc = new InsertDocumentRequest(index: "test_pq", doc: doc);
indexApi.Insert(newdoc);
let mut pq_doc = HashMap::new();
pq_doc.insert("q1".to_string(), serde_json::json!("@title shoes"));
pq_doc.insert("filters".to_string(), serde_json::json!("price>5"));
pq_doc.insert("tags".to_string(), serde_json::json!(["Louis Vitton"]));
let mut doc = HashMap::new();
pq_doc.insert("query".to_string(), serde_json::json!(pq_doc));
let insert_req = InsertDocumentRequest::new("test_pq".to_string(), serde_json::json!(doc));
let insert_res = index_api.insert(insert_req).await;
+---------------------+-----------+------+---------+
| id | query | tags | filters |
+---------------------+-----------+------+---------+
| 1657843905795719192 | wristband | | price>5 |
+---------------------+-----------+------+---------+
{
"table": "pq_table",
"type": "doc",
"_id": 1657843905795719196,
"result": "created"
}
{
"table": "pq_table",
"type": "doc",
"_id": 1657843905795719198,
"result": "created"
}
Array(
[index] => pq_table
[type] => doc
[_id] => 1657843905795719198
[result] => created
)
{'created': True,
'found': None,
'id': 1657843905795719198,
'table': 'test_pq',
'result': 'created'}
{'created': True,
'found': None,
'id': 1657843905795719198,
'table': 'test_pq',
'result': 'created'}
{"table":"test_pq","_id":1657843905795719198,"created":true,"result":"created"}
In case of omitted schema in SQL INSERT
command, the following parameters are expected:
- ID. You can use
0
as the ID to trigger auto-ID generation. - Query - Full-text query.
- Tags - PQ rule tags string.
- Filters - Additional filters by attributes.
- SQL
INSERT INTO pq VALUES (0, '@title shoes', '', '');
INSERT INTO pq VALUES (0, '@title shoes', 'Louis Vuitton', '');
SELECT * FROM pq;
+---------------------+--------------+---------------+---------+
| id | query | tags | filters |
+---------------------+--------------+---------------+---------+
| 2810855531667783688 | @title shoes | | |
| 2810855531667783689 | @title shoes | Louis Vuitton | |
+---------------------+--------------+---------------+---------+
To replace an existing PQ rule with a new one in SQL, just use a regular REPLACE command. There's a special syntax ?refresh=1
to replace a PQ rule defined in JSON mode via the HTTP JSON interface.
- SQL
- JSON
mysql> select * from pq;
+---------------------+--------------+------+---------+
| id | query | tags | filters |
+---------------------+--------------+------+---------+
| 2810823411335430148 | @title shoes | | |
+---------------------+--------------+------+---------+
1 row in set (0.00 sec)
mysql> replace into pq(id,query) values(2810823411335430148,'@title boots');
Query OK, 1 row affected (0.00 sec)
mysql> select * from pq;
+---------------------+--------------+------+---------+
| id | query | tags | filters |
+---------------------+--------------+------+---------+
| 2810823411335430148 | @title boots | | |
+---------------------+--------------+------+---------+
1 row in set (0.00 sec)
GET /pq/pq/doc/2810823411335430149
{
"took": 0,
"timed_out": false,
"hits": {
"total": 1,
"hits": [
{
"_id": 2810823411335430149,
"_score": 1,
"_source": {
"query": {
"match": {
"title": "shoes"
}
},
"tags": "",
"filters": ""
}
}
]
}
}
PUT /pq/pq/doc/2810823411335430149?refresh=1 -d '{
"query": {
"match": {
"title": "boots"
}
}
}'
GET /pq/pq/doc/2810823411335430149
{
"took": 0,
"timed_out": false,
"hits": {
"total": 1,
"hits": [
{
"_id": 2810823411335430149,
"_score": 1,
"_source": {
"query": {
"match": {
"title": "boots"
}
},
"tags": "",
"filters": ""
}
}
]
}
}
You can ingest data into Manticore from external storages using various methods:
- Indexer tool to fetch data from various databases into plain tables.
- Logstash, Filebeat, and Vector.dev integrations to put data to Manticore real-time tables from these tools.
- Kafka integration to synchronize data from Kafka topics into a real-time table.