返回参数的绝对值。
返回两个参数的反正切函数,以弧度为单位表达。
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。
类型转换包括三种主要操作:转换、重新解释和提升。
- 转换。指将一个值的数据类型更改为另一种数据类型的过程。这涉及额外的计算,仅由
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() 的比较)一起使用时,如果多值属性的所有值都在比较值中找到,则返回 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> 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() 的比较)一起使用时,如果多值属性中的任何一个值在比较值中找到,则返回 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> 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 中的版本略有不同。它接受三个参数,检查第一个参数是否等于 0.0,如果不为零,则返回第二个参数,如果为零,则返回第三个参数。请注意,与比较运算符不同,IF() 不使用阈值!因此,可以安全地将比较结果用作其第一个参数,但算术运算符可能会产生意外的结果。例如,以下两个调用即使它们是逻辑等价的也会产生不同的结果:
- 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,...) 接受两个或更多参数,并返回如果第一个参数 (expr) 等于其他参数中的任何一个 (val1..valN),则返回 1,否则返回 0。当前,所有检查的值(但不是表达式本身)都必须是常量。这些常量会被预先排序,并使用二分查找,因此即使面对一个大型任意列表,IN() 也会非常快速。第一个参数也可以是一个 MVA 属性。在这种情况下,IN() 将返回 1 如果任何 MVA 值等于其他参数中的任何一个。IN() 还支持 IN(expr,@uservar) 的语法来检查值是否属于给定的全局用户变量中的列表。第一个参数可以是一个 JSON 属性。
INDEXOF(cond FOR var IN json.array) 函数遍历数组中的所有元素,并返回第一个满足 'cond' 为真的元素的索引,如果没有元素满足 'cond' 则返回 -1。
INTERVAL(expr,point1,point2,point3,...) 接受两个或更多参数,并返回第一个参数小于该参数的参数的索引:如果 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,并在这种情况下将其放在最后。