在SQL分析语句中,您可以使用search函数对日志数据执行全文检索。本文介绍search函数的使用示例、使用限制、最佳实践建议和常见问题。
前提条件
已创建Standard LogStore。具体操作,请参见管理LogStore。
已采集日志。具体操作,请参见数据采集概述。
已创建索引,且非扫描模式。
使用示例
与SQL谓词组合
search函数可以与标准SQL谓词通过AND组合使用,实现更精细的过滤。
-- search + 比较运算符
* | SELECT * FROM log
WHERE search('status: 200') AND request_time > 100
-- search + IN 子句
* | SELECT * FROM log
WHERE search('request_method: GET') AND status IN (200, 301, 302)
-- search + LIKE
* | SELECT * FROM log
WHERE search('status: 200') AND http_user_agent LIKE '%Chrome%'
-- search + BETWEEN
* | SELECT * FROM log
WHERE search('request_method: POST') AND request_time BETWEEN 100 AND 500
-- search + 复杂条件组合(OR不包含search即可)
* | SELECT * FROM log
WHERE search('request_method: GET')
AND (status = 200 OR status = 302)
AND request_time > 50search函数与其他SQL谓词只能使用AND连接。
search函数不能出现在OR的任何层级中。例如
search('error') OR status = 500是不允许的。OR可以用于非search的其他SQL谓词条件。例如
search('error') AND (status = 500 OR status = 502)。
多表JOIN场景
search函数支持在多LogStore JOIN场景下使用。每个参与JOIN的子查询可以独立应用各自的search()过滤条件,互不干扰。
每个子查询中仍然只能有一个search()函数。多表JOIN之所以可以有多个search(),是因为每个search()分属不同的子查询。
样例数据说明
以下示例使用订单表(orders LogStore)和用户表(users LogStore)进行说明。
订单表(orders LogStore)Schema:
字段名 | 字段类型 | 说明 |
order_id | long | 订单ID |
user_id | long | 用户ID,关联用户表 |
status | text | 订单状态,如completed、pending、cancelled |
amount | double | 订单金额 |
order_type | text | 订单类型,如normal、vip |
用户表(users LogStore)Schema:
字段名 | 字段类型 | 说明 |
user_id | long | 用户ID,主键 |
username | text | 用户名 |
region | text | 用户所在地域,如hangzhou、shanghai、beijing |
text | 用户邮箱 | |
age | long | 用户年龄 |
INNER JOIN
查询已完成订单(status为completed)对应的杭州地域(region为hangzhou)用户信息。
* | SELECT o.order_id, o.status, o.amount, u.username, u.region
FROM (
SELECT * FROM orders.log
WHERE search('status: completed')
) o
JOIN (
SELECT * FROM users.log
WHERE search('region: hangzhou')
) u
ON o.user_id = u.user_id
ORDER BY o.order_idLEFT JOIN
保留所有已完成订单,仅匹配上海地域的用户。未匹配到用户的订单,用户相关字段显示为null。
* | SELECT o.order_id, o.status, u.username, u.region
FROM (
SELECT * FROM orders.log
WHERE search('status: completed')
) o
LEFT JOIN (
SELECT * FROM users.log
WHERE search('region: shanghai')
) u
ON o.user_id = u.user_id
ORDER BY o.order_id自连接(Self-Join)
同一LogStore的自连接,对不同别名的子查询分别应用不同的查询条件。
假设员工表(employees LogStore)Schema如下:
字段名 | 字段类型 | 说明 |
employee_id | long | 员工ID |
employee_name | text | 员工姓名 |
department | text | 部门,如engineering、finance |
level | text | 职级,如junior、senior |
manager_id | long | 上级经理的employee_id |
查询engineering部门员工及其senior级别的经理信息:
* | SELECT e.employee_name AS employee, e.department,
m.employee_name AS manager, m.level AS manager_level
FROM (
SELECT * FROM employees.log
WHERE search('department: engineering')
) e
JOIN (
SELECT * FROM employees.log
WHERE search('level: senior')
) m
ON e.manager_id = m.employee_id
ORDER BY e.employee_name使用限制
限制项 | 说明 |
单实例限制 | 每个子查询(底层SELECT)中只能使用一个 |
OR操作符限制 |
|
扫描模式限制 | 扫描模式下不支持search函数。 |
查询语法输入冲突 | 当查询语法输入包含实际过滤条件时,不能使用search函数。查询语法输入为空或为 |
参数类型 | search函数的参数只能是字符串字面量,不支持列引用、变量或函数表达式等动态值。 |
组合用法限制
场景 | 是否允许 | 示例 |
单个search函数 | 允许 |
|
search + AND + SQL条件 | 允许 |
|
search + AND + (c1 OR c2) | 允许 |
|
search内部使用OR | 允许 |
|
多表JOIN各子查询含search | 允许 | 每个子查询独立使用,互不影响 |
同一子查询中多个search | 不允许 |
|
search + OR + SQL条件 | 不允许 |
|
最佳实践
合并查询条件:将所有全文检索条件合并到一个
search()调用中,避免使用多个search()函数。使用字段限定查询:尽量使用
field: value格式而非全文查询,提高查询精度和性能。利用数值类型:long、double类型的字段使用范围查询(
field in [min max])而非文本匹配。JSON字段使用子字段路径:查询JSON类型字段时,使用精确的子字段路径(如
content.status),避免在父字段层级进行模糊匹配。合理组合SQL谓词:search函数适合用于全文检索和索引下推过滤,SQL谓词适合用于精确的数值比较和条件判断。二者通过AND组合使用,可以兼顾性能和灵活性。
常见问题
报错key (xxx) is not config as key value config
查询的字段未在索引中配置为字段索引。请检查索引配置,确认该字段已创建字段索引。
报错Multiple search() functions in a single query are not supported
同一个子查询中使用了多个search函数。请将多个查询条件合并为一个search调用,例如将search('error') AND search('timeout')改为search('error AND timeout')。
报错The search() function cannot be combined with OR operator
search函数与其他条件使用了OR连接。请将OR逻辑移到search函数内部,例如将search('error') OR status = 500改为search('error OR status: 500')。
报错The search() function is not supported in scan mode
当前处于扫描模式,该模式不支持search函数。请切换为索引模式使用。