返回参数的绝对值。
返回两个参数的反正切函数,结果以弧度表示。
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。
类型转换包括三个主要操作:转换、重新解释和提升。
- 转换。指将一个值的数据类型更改为另一种数据类型的过程。这涉及额外的计算,仅由
TO_STRING()函数执行。 - 重新解释。指将表示一个值的二进制数据视为另一种数据类型,而不实际更改底层数据。由
SINT()处理,不涉及额外计算;它只是重新解释现有数据。 - 提升。指将一个值转换为“更大”或更精确的数据类型的过程。它也不需要额外计算;它只是请求参数提供不同类型的值。只有 JSON 字段和少数其他函数可以将其值提升为整数。如果参数无法产生不同类型的值,提升将失败。例如,
TIMEDIFF()函数通常返回字符串,但也可以返回数字。因此,BIGINT(TIMEDIFF(1,2))会成功执行,强制TIMEDIFF()提供整数值。相反,DATE_FORMAT()仅返回字符串,不能产生数字,这意味着BIGINT(DATE_FORMAT(...))会失败。
此函数将整数参数提升为 64 位类型,浮点参数保持不变。它旨在确保特定表达式(如 a*b)以 64 位模式计算,即使所有参数都是 32 位。
DOUBLE() 函数将其参数提升为浮点类型。此设计用于强制计算数值 JSON 字段。
INTEGER() 函数将其参数提升为 64 位有符号类型。此设计用于强制计算数值 JSON 字段。
此函数强制将其参数转换为字符串类型。
UINT() 函数将其参数提升为 32 位无符号整数类型。
UINT64() 函数将其参数提升为 64 位无符号整数类型。
SINT() 函数强制将其 32 位无符号整数参数重新解释为有符号,并扩展为 64 位类型(因为 32 位类型是无符号的)。例如,1-2 通常计算为 4294967295,但 SINT(1-2) 计算为 -1。
ALL(cond FOR var IN json.array) 适用于 JSON 数组,如果数组中所有元素都满足条件,则返回 1,否则返回 0。cond 是一个通用表达式,也可以在其中使用 var 作为当前数组元素的值。
- ALL() with json
- ALL() with json ex. 2
select *, ALL(x>0 AND x<4 FOR x IN j.ar) from tblselect *, ALL(x>0 AND x<4 FOR x IN j.ar) cond from tbl where cond=1+------+--------------+--------------------------------+
| id | j | all(x>0 and x<4 for x in j.ar) |
+------+--------------+--------------------------------+
| 1 | {"ar":[1,3]} | 1 |
| 2 | {"ar":[3,7]} | 0 |
+------+--------------+--------------------------------+
2 rows in set (0.00 sec)+------+--------------+------+
| id | j | cond |
+------+--------------+------+
| 1 | {"ar":[1,3]} | 1 |
+------+--------------+------+
1 row in set (0.00 sec)ALL(mva) 是多值属性的特殊构造函数。当与比较运算符(包括与 IN() 的比较)一起使用时,如果 MVA 属性中的所有值都在被比较的值中,则返回 1。
- ALL() with MVA
- ALL() with MVA and IN()
select * from tbl where all(m) >= 1select * from tbl where all(m) in (1, 3, 7, 10)+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)要将 MVA 属性与数组进行比较,避免使用 <mva> NOT ALL();应使用 ALL(<mva>) NOT IN()。
- ALL() with MVA and NOT IN()
select * from tbl where all(m) not in (2, 4)+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)ALL(string list) 是用于过滤字符串标签的特殊操作。
如果 ALL() 的所有参数中列举的单词都存在于属性中,则过滤器匹配。可选的 NOT 会反转逻辑。
此过滤器内部使用逐文档匹配,因此在全扫描查询的情况下,可能比预期更慢。它适用于未建立索引的属性,如计算表达式或 PQ 表中的标签。如果需要此类过滤,建议将字符串属性作为全文字段,然后使用全文操作符 match(),这将调用全文搜索。
- ALL() with strings
- ALL() with strings and NOT
select * from tbl where tags all('bug', 'release')mysql> select * from tbl
+------+---------------------------+
| id | tags |
+------+---------------------------+
| 1 | bug priority_high release |
| 2 | bug priority_low release |
+------+---------------------------+
2 rows in set (0.00 sec)
mysql> select * from tbl where tags not all('bug')
Empty set (0.00 sec)+------+---------------------------+
| id | tags |
+------+---------------------------+
| 1 | bug priority_high release |
| 2 | bug priority_low release |
+------+---------------------------+
2 rows in set (0.00 sec)ANY(cond FOR var IN json.array) 适用于 JSON 数组,如果数组中任一元素满足条件,则返回 1,否则返回 0。cond 是一个通用表达式,也可以在其中使用 var 作为当前数组元素的值。
- ANY() with json
- ANY() with json ex. 2
select *, ANY(x>5 AND x<10 FOR x IN j.ar) from tblselect *, ANY(x>5 AND x<10 FOR x IN j.ar) cond from tbl where cond=1+------+--------------+---------------------------------+
| id | j | any(x>5 and x<10 for x in j.ar) |
+------+--------------+---------------------------------+
| 1 | {"ar":[1,3]} | 0 |
| 2 | {"ar":[3,7]} | 1 |
+------+--------------+---------------------------------+
2 rows in set (0.00 sec)+------+--------------+------+
| id | j | cond |
+------+--------------+------+
| 2 | {"ar":[3,7]} | 1 |
+------+--------------+------+
1 row in set (0.00 sec)ANY(mva) 是多值属性的特殊构造函数。当与比较运算符(包括与 IN() 的比较)一起使用时,如果 MVA 属性中的任一值在被比较的值中,则返回 1。
当使用 IN() 比较数组时,如果未另行指定,默认假设为 ANY(),但会发出缺少构造函数的警告。
- ANY() with MVA
- ANY() with MVA and IN()
mysql> select * from tbl
+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.01 sec)
mysql> select * from tbl where any(m) > 5
+------+------+
| id | m |
+------+------+
| 2 | 3,7 |
+------+------+
1 row in set (0.00 sec)select * from tbl where any(m) in (1, 7, 10)+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)要将 MVA 属性与数组进行比较,避免使用 <mva> NOT ANY();应使用 <mva> NOT IN() 或 ANY(<mva>) NOT IN()。
- ANY() with MVA and NOT IN()
mysql> select * from tbl
+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)
mysql> select * from tbl where any(m) not in (1, 3, 5)
+------+------+
| id | m |
+------+------+
| 2 | 3,7 |
+------+------+
1 row in set (0.00 sec)ANY(string list) 是用于过滤字符串标签的特殊操作。
如果 ANY() 的参数中列举的任一单词存在于属性中,则过滤器匹配。可选的 NOT 会反转逻辑。
此过滤器内部使用逐文档匹配,因此在全扫描查询的情况下,可能比预期更慢。它适用于未建立索引的属性,如计算表达式或 PQ 表中的标签。如果需要此类过滤,建议将字符串属性作为全文字段,然后使用全文操作符 match(),这将调用全文搜索。
- ANY() with strings
- ANY() with strings and NOT
select * from tbl where tags any('bug', 'feature')select * from tbl
--------------
+------+---------------------------+
| id | tags |
+------+---------------------------+
| 1 | bug priority_high release |
| 2 | bug priority_low release |
+------+---------------------------+
2 rows in set (0.00 sec)
--------------
select * from tbl where tags not any('feature', 'priority_low')
--------------
+------+---------------------------+
| id | tags |
+------+---------------------------+
| 1 | bug priority_high release |
+------+---------------------------+
1 row in set (0.01 sec)+------+---------------------------+
| id | tags |
+------+---------------------------+
| 1 | bug priority_high release |
| 2 | bug priority_low release |
+------+---------------------------+
2 rows in set (0.00 sec)CONTAINS(polygon, x, y) 检查点 (x,y) 是否在给定多边形内,若是则返回 1,否则返回 0。多边形必须使用 POLY2D() 函数指定。前者函数适用于“较小”的多边形,指边长小于 500 公里(300 英里),且为了速度不考虑地球曲率。对于较大距离,应使用 GEOPOLY2D,它将给定多边形分割成更小部分,考虑地球曲率。
IF() 的行为与其 MySQL 对应函数略有不同。它接受 3 个参数,检查第 1 个参数是否等于 0.0,如果不为零则返回第 2 个参数,否则返回第 3 个参数。注意,与比较运算符不同,IF() 不 使用阈值!因此,使用比较结果作为第 1 个参数是安全的,但算术运算符可能产生意外结果。例如,以下两个调用即使逻辑上等价,结果也会不同:
- IF()
IF ( sqrt(3)*sqrt(3)-3<>0, a, b )
IF ( sqrt(3)*sqrt(3)-3, a, b )在第一种情况下,比较运算符 <> 会因阈值返回 0.0(假),IF() 将始终返回 ** 作为结果。在第二种情况下,相同的 sqrt(3)*sqrt(3)-3 表达式将由 IF() 函数自身不带阈值地与零比较。然而,由于浮点计算精度有限,其值会略微不同于零。因此,IF() 对 0.0 的比较不会通过,第二种变体将返回 'a' 作为结果。
HISTOGRAM(expr, {hist_interval=size, hist_offset=value}) 接受一个桶大小并返回该值所属的桶编号。关键函数是:
key_of_the_bucket = interval + offset * floor ( ( value - offset ) / interval )
直方图参数 interval 必须为正。直方图参数 offset 必须为正且小于 interval。它用于聚合、FACET 和分组。
- HISTOGRAM()
SELECT COUNT(*),
HISTOGRAM(price, {hist_interval=100}) as price_range
FROM facets
GROUP BY price_range ORDER BY price_range ASC;IN(expr,val1,val2,...) 接受 2 个或更多参数,如果第一个参数(expr)等于其他任一参数(val1..valN),则返回 1,否则返回 0。目前,所有被检查的值(但不包括表达式本身)必须是常量。常量会被预先排序,并使用二分查找,因此即使是针对大量任意常量列表的 IN() 也会非常快。第一个参数也可以是 MVA 属性。在这种情况下,如果任何 MVA 值等于其他任一参数,IN() 将返回 1。IN() 还支持 IN(expr,@uservar) 语法,用于检查值是否属于给定全局用户变量中的列表。第一个参数可以是 JSON 属性。
INDEXOF(cond FOR var IN json.array) 函数遍历数组中的所有元素,返回第一个满足 'cond' 条件的元素的索引,如果数组中所有元素都不满足 'cond',则返回 -1。
INTERVAL(expr,point1,point2,point3,...) 接受 2 个或更多参数,返回第一个小于第一个参数的参数的索引:如果 expr<point1 返回 0,point1<=expr<point2 返回 1,依此类推。要求 point1<point2<...<pointN,该函数才能正确工作。
LENGTH(attr_mva) 函数返回 MVA 集合中的元素数量。它适用于 32 位和 64 位 MVA 属性。LENGTH(attr_json) 返回 JSON 字段的长度。返回值取决于字段类型。例如,LENGTH(json_attr.some_int) 总是返回 1,而 LENGTH(json_attr.some_array) 返回数组中的元素数量。LENGTH(string_expr) 函数返回表达式结果字符串的长度。
TO_STRING() 必须包裹表达式,无论表达式返回的是非字符串还是简单的字符串属性。
RANGE(expr, {range_from=value,range_to=value}) 接受一组范围并返回该值所属的桶编号。
该表达式包含每个范围的 range_from 值,但不包含 range_to 值。范围可以是开放的——只有 range_from 或只有 range_to。它用于聚合、FACET 和分组。
- RANGE()
SELECT COUNT(*),
RANGE(price, {range_to=150},{range_from=150,range_to=300},{range_from=300}) price_range
FROM facets
GROUP BY price_range ORDER BY price_range ASC;REMAP(condition, expression, (cond1, cond2, ...), (expr1, expr2, ...)) 函数允许根据条件值对表达式值做一些例外处理。条件表达式应始终返回整数,而表达式可以返回整数或浮点数。
- REMAP()
- Another example
SELECT id, size, REMAP(size, 15, (5,6,7,8), (1,1,2,2)) s
FROM products
ORDER BY s ASC;SELECT REMAP(userid, karmapoints, (1, 67), (999, 0)) FROM users;
SELECT REMAP(id%10, salary, (0), (0.0)) FROM employes;这将使大小为 5 和 6 的文档排在前面,接着是大小为 7 和 8 的文档。如果存在未列在数组中的原始值(例如大小为 10),则默认值为 15,在这种情况下,将排在最后。