ALTER TABLE table ADD COLUMN column_name [{INTEGER|INT|BIGINT|FLOAT|BOOL|MULTI|MULTI64|JSON|STRING|TIMESTAMP|TEXT [INDEXED [ATTRIBUTE]]}] [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- 多值大整数属性json- json 属性string/text attribute/string attribute- 字符串属性text/text indexed stored/string indexed stored- 全文索引字段,原始值存储在文档存储中text indexed/string indexed- 仅全文索引字段(原始值不存储在文档存储中)text indexed attribute/string indexed attribute- 全文索引字段 + 字符串属性(不在文档存储中存储原始值)text stored/string stored- 仅存储在文档存储中,不做全文索引,也不是字符串属性- 给任何属性(除 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 模式下的全文设置。但这只影响新文档,已有文档不受影响。
示例:
- 创建一个带有全文字段和只允许 3 个可搜索字符(
a、b和c)的charset_table的表。 - 然后插入文档 '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 可以是常数整数或整数属性名。
如果使用 seed,请注意它会分别为每个普通表、RT 磁盘、RAM 块或伪分片重置 rand() 的起点。因此,对分布式表的任何形式查询可能返回多个相同的随机值。
返回参数的正弦值。
返回参数的平方根。
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
如果排序键是浮点数,则返回当前 top-N 匹配中排名最差元素的排序键值,否则返回 0。
返回当前 top-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 计算可以推迟到外层排序,只对内层限制的前 100 个 WEIGHT() 匹配执行。这意味着 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 中匹配。
QUERY() 返回当前搜索查询。QUERY() 是一个后限制表达式,旨在与 SNIPPET() 一起使用。
表函数是一种用于查询后结果集处理的机制。表函数以任意结果集作为输入,并返回一个新的、处理过的结果集作为输出。第一个参数应为输入结果集,但表函数可以选择性地接受和处理更多参数。表函数可以完全改变结果集,包括其模式。目前,仅支持内置表函数。表函数适用于外部 SELECT 和嵌套 SELECT。