ALTER TABLE table ADD COLUMN column_name [{INTEGER|INT|BIGINT|FLOAT|BOOL|MULTI|MULTI64|JSON [secondary_index='1']|STRING|TEXT [INDEXED [ATTRIBUTE]]|TIMESTAMP}] [engine='columnar']
ALTER TABLE table DROP COLUMN column_name
ALTER TABLE table MODIFY COLUMN column_name bigint
此功能仅支持为RT表一次添加一个字段,或将int列扩展为bigint。支持的数据类型包括:
int- 整数属性timestamp- 时间戳属性bigint- 大整数属性float- 浮点数属性bool- 布尔属性multi- 多值整数属性multi64- 多值bigint属性json- JSON 属性;使用secondary_index='1'为 JSON 创建二级索引string/text attribute/string attribute- 字符串属性text/text indexed stored/string indexed stored- 全文索引字段,原始值存储在docstore中text indexed/string indexed- 全文索引字段,仅索引(原始值不存储在docstore中)text indexed attribute/string indexed attribute- 全文索引字段 + 字符串属性(不将原始值存储在docstore中)text stored/string stored- 值仅存储在docstore中,不进行全文索引,也不是字符串属性- 为任何属性(json除外)添加
engine='columnar'将使其存储在列式存储中
- ❗建议在
ALTER表之前备份表文件,以防突然断电或其他类似问题导致数据损坏。 - 添加列时无法查询表。
- 新创建的属性值设置为0。
ALTER不适用于分布式表和无任何属性的表。- 不能删除
id列。 - 当删除一个既是全文字段又是字符串属性的字段时,第一次
ALTER DROP删除属性,第二次删除全文字段。 - 添加/删除全文字段仅在RT模式下支持。
- Example
mysql> desc rt;
+------------+-----------+
| Field | Type |
+------------+-----------+
| id | bigint |
| text | field |
| group_id | uint |
| date_added | timestamp |
+------------+-----------+
mysql> alter table rt add column test integer;
mysql> desc rt;
+------------+-----------+
| Field | Type |
+------------+-----------+
| id | bigint |
| text | field |
| group_id | uint |
| date_added | timestamp |
| test | uint |
+------------+-----------+
mysql> alter table rt drop column group_id;
mysql> desc rt;
+------------+-----------+
| Field | Type |
+------------+-----------+
| id | bigint |
| text | field |
| date_added | timestamp |
| test | uint |
+------------+-----------+
mysql> alter table rt add column title text indexed;
mysql> desc rt;
+------------+-----------+------------+
| Field | Type | Properties |
+------------+-----------+------------+
| id | bigint | |
| text | text | indexed |
| title | text | indexed |
| date_added | timestamp | |
| test | uint | |
+------------+-----------+------------+
mysql> alter table rt add column title text attribute;
mysql> desc rt;
+------------+-----------+------------+
| Field | Type | Properties |
+------------+-----------+------------+
| id | bigint | |
| text | text | indexed |
| title | text | indexed |
| date_added | timestamp | |
| test | uint | |
| title | string | |
+------------+-----------+------------+
mysql> alter table rt drop column title;
mysql> desc rt;
+------------+-----------+------------+
| Field | Type | Properties |
+------------+-----------+------------+
| id | bigint | |
| text | text | indexed |
| title | text | indexed |
| date_added | timestamp | |
| test | uint | |
+------------+-----------+------------+
mysql> alter table rt drop column title;
mysql> desc rt;
+------------+-----------+------------+
| Field | Type | Properties |
+------------+-----------+------------+
| id | bigint | |
| text | text | indexed |
| date_added | timestamp | |
| test | uint | |
+------------+-----------+------------+ALTER TABLE table ft_setting='value'[, ft_setting2='value']
您可以使用ALTER在RT模式下修改表的全文设置。但是,它只影响新文档,不影响现有文档。
示例:
- 创建一个具有全文字段和
charset_table的表,该表只允许3个可搜索字符:a、b和c。 - 然后我们插入文档'abcd'并通过查询
abcd找到它,d被忽略,因为它不在charset_table数组中 - 然后我们意识到,我们也希望
d可搜索,因此我们借助ALTER添加它 - 但相同的查询
where match('abcd')仍然显示它搜索的是abc,因为现有文档记住了charset_table的先前内容 - 然后我们添加另一个文档
abcd并再次搜索abcd - 现在它找到了两个文档,并且
show meta显示它使用了两个关键词:abc(用于查找旧文档)和abcd(用于新文档)。
- Example
mysql> create table rt(title text) charset_table='a,b,c';
mysql> insert into rt(title) values('abcd');
mysql> select * from rt where match('abcd');
+---------------------+-------+
| id | title |
+---------------------+-------+
| 1514630637682688054 | abcd |
+---------------------+-------+
mysql> show meta;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| total | 1 |
| total_found | 1 |
| time | 0.000 |
| keyword[0] | abc |
| docs[0] | 1 |
| hits[0] | 1 |
+---------------+-------+
mysql> alter table rt charset_table='a,b,c,d';
mysql> select * from rt where match('abcd');
+---------------------+-------+
| id | title |
+---------------------+-------+
| 1514630637682688054 | abcd |
+---------------------+-------+
mysql> show meta
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| total | 1 |
| total_found | 1 |
| time | 0.000 |
| keyword[0] | abc |
| docs[0] | 1 |
| hits[0] | 1 |
+---------------+-------+
mysql> insert into rt(title) values('abcd');
mysql> select * from rt where match('abcd');
+---------------------+-------+
| id | title |
+---------------------+-------+
| 1514630637682688055 | abcd |
| 1514630637682688054 | abcd |
+---------------------+-------+
mysql> show meta;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| total | 2 |
| total_found | 2 |
| time | 0.000 |
| keyword[0] | abc |
| docs[0] | 1 |
| hits[0] | 1 |
| keyword[1] | abcd |
| docs[1] | 1 |
| hits[1] | 1 |
+---------------+-------+您可以在RT模式下更改实时表的名称。
ALTER TABLE table_name RENAME new_table_name;
注意:重命名实时表需要Manticore Buddy。如果不起作用,请确保Buddy已安装。
- Example
ALTER TABLE table_name RENAME new_table_name;Query OK, 0 rows affected (0.00 sec)ALTER TABLE table RECONFIGURE
ALTER还可以在普通模式下重新配置RT表,以便配置文件中的新分词、词法分析和其他文本处理设置对新文档生效。注意,现有文档将保持不变。在内部,它会强制将当前RAM块保存为新的磁盘块,并调整表头,以便使用更新的全文设置对新文档进行分词。
- Example
mysql> show table rt settings;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| settings | |
+---------------+-------+
1 row in set (0.00 sec)
mysql> alter table rt reconfigure;
Query OK, 0 rows affected (0.00 sec)
mysql> show table rt settings;
+---------------+----------------------+
| Variable_name | Value |
+---------------+----------------------+
| settings | morphology = stem_en |
+---------------+----------------------+
1 row in set (0.00 sec)ALTER TABLE table REBUILD SECONDARY
您还可以使用ALTER重建给定表中的二级索引。有时,二级索引可能对整个表或表中的一个或多个属性被禁用:
- 当属性更新时,其二级索引将被禁用。
- 如果Manticore加载了一个带有不再支持的旧版本二级索引的表,则整个表的二级索引将被禁用。
ALTER TABLE table REBUILD SECONDARY从属性数据重建二级索引并重新启用它们。
此外,旧版本的二级索引可能受支持,但会缺少某些功能。REBUILD SECONDARY可用于更新二级索引。
- Example
ALTER TABLE rt REBUILD SECONDARY;Query OK, 0 rows affected (0.00 sec)ALTER TABLE table REBUILD KNN
该命令重新处理表中的所有向量数据,并从头开始重建KNN索引。
- Example
ALTER TABLE rt REBUILD KNN;Query OK, 0 rows affected (0.00 sec)当远程模型用于自动嵌入时,可以使用ALTER修改API密钥:
ALTER TABLE table_name MODIFY COLUMN column_name API_KEY='key';
- Example
ALTER TABLE rt MODIFY COLUMN vector API_KEY='key';要更改分布式表中的本地或远程节点列表,请遵循与创建表时相同的语法。只需将命令中的CREATE替换为ALTER,并移除type='distributed':
ALTER TABLE `distr_table_name` [[local='local_table_name'], [agent='host:port:remote_table'] ... ]
注意:在线更改分布式表的模式需要Manticore Buddy。如果不起作用,请确保Buddy已安装。
- Example
ALTER TABLE local_dist local='index1' local='index2' agent='127.0.0.1:9312:remote_table';≫ 函数
返回参数的绝对值。
返回两个参数的反正切函数,以弧度为单位表达。
BITDOT(mask, w0, w1, ...) 返回每个位与权重相乘之和。bit0*w0 + bit1*w1 + ...
返回大于或等于参数的最小整数值。
返回参数的余弦值。
返回字符串参数的CRC32值。
返回参数的指数(e=2.718... 的幂)。
返回第N个斐波那契数,其中N是整数参数。也就是说,参数为0和以上将生成0, 1, 1, 2, 3, 5, 8, 13等值。注意计算使用32位整数数学,因此从第48个数字开始返回模2^32的结果。
返回小于或等于参数的最大整数值。
GREATEST(attr_json.some_array) 函数以JSON数组作为参数,并返回该数组中的最大值。也适用于MVA。
返回第一个参数除以第二个参数的整数结果。两个参数都必须是整数类型。
LEAST(attr_json.some_array) 函数以JSON数组作为参数,并返回该数组中的最小值。也适用于MVA。
返回参数的自然对数(底数为e=2.718...)。
返回参数的常用对数(底数为10)。
返回参数的二进制对数(底数为2)。
返回两个参数中较大的一个。
返回两个参数中较小的一个。
返回第一个参数的第二个参数次方。
返回介于0和1之间的随机浮点数。可以可选地接受一个seed,它可以是一个常量整数或一个整数属性的名称。
如果您使用了seed,请记住它会分别重置rand()的起始点,对于每个普通表、RT磁盘、RAM块或伪分片。因此,任何形式的分布式表查询可能会返回多个相同的随机值。
返回参数的正弦值。
返回参数的平方根。
BM25A(k1,b) 返回精确的 BM25A() 值。需要 expr 排序器并且启用了 index_field_lengths。参数 k1 和 b 必须是浮点数。
BM25F(k1, b, {field=weight, ...}) 返回精确的 BM25F() 值,并且需要启用 index_field_lengths。还需要 expr 排序器。参数 k1 和 b 必须是浮点数。
用默认值替换不存在的列。它返回由 'attr-name' 指定的属性值,或者如果该属性不存在,则返回 'default-value'。STRING 或 MVA 属性不支持。此函数在搜索具有不同模式的多个表时很有用。
SELECT *, EXIST('gid', 6) as cnd FROM i1, i2 WHERE cnd>5
如果排序键是浮点数,则返回当前前 N 匹配中最差排名元素的排序键值;否则返回 0。
返回当前前 N 匹配中最差排名元素的权重。
PACKEDFACTORS() 可以用于查询中显示匹配或匹配期间计算的所有加权因子,也可以提供二进制属性以创建自定义排名 UDF。此函数仅在指定表达式排序器且查询不是全扫描时有效;否则返回错误。PACKEDFACTORS() 可以接受一个可选参数来禁用 ATC 排名因子计算:PACKEDFACTORS({no_atc=1})。计算 ATC 显著减慢了查询处理速度,因此如果只需要查看排名因子但不需要 ATC,此选项很有用。PACKEDFACTORS() 还可以输出为 JSON 格式:PACKEDFACTORS({json=1})。以下是在键值对或 JSON 格式下的相应输出示例。(注意,下面的示例是为了可读性而换行的;实际返回值会是一行。)
mysql> SELECT id, PACKEDFACTORS() FROM test1
-> WHERE MATCH('test one') OPTION ranker=expr('1') \G
*************************** 1\. row ***************************
id: 1
packedfactors(): bm25=569, bm25a=0.617197, field_mask=2, doc_word_count=2,
field1=(lcs=1, hit_count=2, word_count=2, tf_idf=0.152356,
min_idf=-0.062982, max_idf=0.215338, sum_idf=0.152356, min_hit_pos=4,
min_best_span_pos=4, exact_hit=0, max_window_hits=1, min_gaps=2,
exact_order=1, lccs=1, wlccs=0.215338, atc=-0.003974),
word0=(tf=1, idf=-0.062982),
word1=(tf=1, idf=0.215338)
1 row in set (0.00 sec)
mysql> SELECT id, PACKEDFACTORS({json=1}) FROM test1
-> WHERE MATCH('test one') OPTION ranker=expr('1') \G
*************************** 1\. row ***************************
id: 1
packedfactors({json=1}):
{
"bm25": 569,
"bm25a": 0.617197,
"field_mask": 2,
"doc_word_count": 2,
"fields": [
{
"lcs": 1,
"hit_count": 2,
"word_count": 2,
"tf_idf": 0.152356,
"min_idf": -0.062982,
"max_idf": 0.215338,
"sum_idf": 0.152356,
"min_hit_pos": 4,
"min_best_span_pos": 4,
"exact_hit": 0,
"max_window_hits": 1,
"min_gaps": 2,
"exact_order": 1,
"lccs": 1,
"wlccs": 0.215338,
"atc": -0.003974
}
],
"words": [
{
"tf": 1,
"idf": -0.062982
},
{
"tf": 1,
"idf": 0.215338
}
]
}
1 row in set (0.01 sec)
此函数可用于在 UDF 中实现自定义排名函数,如下所示:
SELECT *, CUSTOM_RANK(PACKEDFACTORS()) AS r
FROM my_index
WHERE match('hello')
ORDER BY r DESC
OPTION ranker=expr('1');
其中 CUSTOM_RANK() 是在 UDF 中实现的一个函数。它应该声明一个 SPH_UDF_FACTORS 结构(定义在 sphinxudf.h 中),初始化此结构,在使用前将因子解包到其中,并在使用后进行反初始化,如下所示:
SPH_UDF_FACTORS factors;
sphinx_factors_init(&factors);
sphinx_factors_unpack((DWORD*)args->arg_values[0], &factors);
// ... can use the contents of factors variable here ...
sphinx_factors_deinit(&factors);
PACKEDFACTORS() 数据在所有查询阶段都可用,而不仅仅是初始匹配和排名阶段。这使 PACKEDFACTORS() 的另一个特别有趣的用途成为可能:重新排名。
在上面的例子中,我们使用了一个基于表达式的排序器和一个假表达式,并按我们的 UDF 计算出的值对结果集进行了排序。换句话说,我们使用 UDF 对所有结果进行了排序。现在,假设为了举例说明,我们的 UDF 计算非常昂贵,吞吐量仅为每秒 10,000 次调用。如果我们查询匹配了 1,000,000 个文档,我们希望使用一个更简单的表达式来进行大部分排序,以便保持合理的性能。然后,我们将只对前 100 个结果应用昂贵的 UDF。换句话说,我们将使用一个更简单的排名函数构建前 100 个结果,然后再用一个更复杂的函数对其进行重新排序。这可以通过子查询完成:
SELECT * FROM (
SELECT *, CUSTOM_RANK(PACKEDFACTORS()) AS r
FROM my_index WHERE match('hello')
OPTION ranker=expr('sum(lcs)*1000+bm25')
ORDER BY WEIGHT() DESC
LIMIT 100
) ORDER BY r DESC LIMIT 10
在这个例子中,对于每个匹配的文档,基于表达式的排序器都会计算 WEIGHT(),因此会被调用 1,000,000 次。然而,UDF 计算可以推迟到外部排序,并且只会在 WEIGHT() 的前 100 个匹配中执行,根据内部限制。这意味着 UDF 将只会被调用 100 次。最后,根据 UDF 值选择并返回前 10 个结果给应用程序。
作为参考,在分布式设置中,PACKEDFACTORS() 数据将以二进制格式从代理发送到主节点。这使得在主节点上实现额外的重新排序步骤成为技术上可行的。
当在 SQL 中使用但未从任何 UDF 调用时,PACKEDFACTORS() 的结果以纯文本格式呈现,可用于手动评估排名因子。请注意,此功能目前不被 Manticore API 支持。
REMOVE_REPEATS ( result_set, column, offset, limit ) - 删除具有相同 'column' 值的重复调整行。
SELECT REMOVE_REPEATS((SELECT * FROM dist1), gid, 0, 10)
请注意,REMOVE_REPEATS 不会影响 搜索查询元信息 中的 total_found。
WEIGHT() 函数返回计算出的匹配得分。如果没有指定排序,则结果按 WEIGHT() 提供的得分降序排序。在上面的示例中,我们首先按权重排序,然后按整数属性排序。
上述搜索执行简单的匹配,所有单词都需要存在。但是我们可以做更多(这只是简单示例):
mysql> SELECT *,WEIGHT() FROM testrt WHERE MATCH('"list of business laptops"/3');
+------+------+-------------------------------------+---------------------------+----------+
| id | gid | title | content | weight() |
+------+------+-------------------------------------+---------------------------+----------+
| 1 | 10 | List of HP business laptops | Elitebook Probook | 2397 |
| 2 | 10 | List of Dell business laptops | Latitude Precision Vostro | 2397 |
| 3 | 20 | List of Dell gaming laptops | Inspirion Alienware | 2375 |
| 5 | 30 | List of ASUS ultrabooks and laptops | Zenbook Vivobook | 2375 |
+------+------+-------------------------------------+---------------------------+----------+
4 rows in set (0.00 sec)
mysql> SHOW META;
+----------------+----------+
| Variable_name | Value |
+----------------+----------+
| total | 4 |
| total_found | 4 |
| total_relation | eq |
| time | 0.000 |
| keyword[0] | list |
| docs[0] | 5 |
| hits[0] | 5 |
| keyword[1] | of |
| docs[1] | 4 |
| hits[1] | 4 |
| keyword[2] | business |
| docs[2] | 2 |
| hits[2] | 2 |
| keyword[3] | laptops |
| docs[3] | 5 |
| hits[3] | 5 |
+----------------+----------+
16 rows in set (0.00 sec)
在这里,我们搜索四个单词,但如果只有四个单词中的三个被找到,也可以匹配。搜索将对包含所有单词的文档进行更高排名。
ZONESPANLIST() 函数返回匹配区间的对。每个对包含匹配区间的标识符、冒号以及匹配区间的顺序编号。例如,如果文档内容为 <emphasis role="bold"><i>text</i> the <i>text</i></emphasis>,并且查询为 'ZONESPAN:(i,b) text',则 ZONESPANLIST() 将返回字符串 "1:1 1:2 2:1",表示第一个区间匹配了在区间 1 和 2 中的 "text",第二个区间仅在区间 1 中匹配了 "text"。
QUERY() 返回当前搜索查询。QUERY() 是一个 postlimit 表达式,并且旨在与 SNIPPET() 一起使用。
表函数是一种用于查询后结果集处理的机制。表函数接收任意结果集作为输入,并返回一个新的、经过处理的结果集作为输出。第一个参数应为输入结果集,但表函数可以选择性地接受和处理更多参数。表函数可以完全改变结果集,包括其模式。目前,仅支持内置表函数。表函数适用于外部SELECT和嵌套SELECT。