配置项作用 #
indices.query.query_string.allowLeadingWildcard 配置项用于控制查询字符串解析器是否允许使用通配符(* 或 ?)作为查询词的开头。
前导通配符查询(如 *search 或 ?query)会导致全索引扫描,严重影响性能。此配置可以禁用此类查询以保护系统。
配置项属性 #
- 配置路径:
indices.query.query_string.allowLeadingWildcard - 数据类型:
Boolean(布尔值) - 默认值:
true - 是否可选: 是
- 作用域: NodeScope(节点级别)
配置项详解 #
工作机制 #
前导通配符查询流程
allowLeadingWildcard = true (默认):
查询: *term
│
↓
解析器接受前导通配符 ✅
│
↓
执行查询
│
↓
全索引扫描 ❌
│
↓
返回结果(可能很慢)
查询: term*
│
↓
解析器接受后缀通配符 ✅
│
↓
使用索引优化
│
↓
执行查询 ✅
allowLeadingWildcard = false:
查询: *term
│
↓
解析器拒绝前导通配符 ❌
│
↓
返回错误:
"Cannot parse '...
leading wildcard is not allowed"
通配符位置说明 #
通配符位置示例
前导通配符(allowLeadingWildcard 控制的):
*term ← * 在开头 ❌
?term ← ? 在开头 ❌
后缀通配符(不受影响):
term* ← * 在结尾 ✅
term? ← ? 在结尾 ✅
中间通配符(不受影响):
te*rm ← * 在中间 ✅
te?rm ← ? 在中间 ✅
全索引扫描问题 #
前导通配符导致的性能问题
查询: *prod
执行计划:
1. 扫描所有分片
2. 读取所有文档
3. 检查每个文档是否包含 "prod"
4. 返回匹配结果
影响:
├── 无法使用索引优化
├── 读取大量磁盘
├── 消耗大量 CPU
├── 查询延迟很高
└── 可能导致 DoS
替代方案:
- 前缀查询: prefix query
- 通配符查询但避免前导: prod*
- 反向索引: 反转词 + ngram
配置建议 #
生产环境(推荐禁用) #
indices:
query:
query_string:
allowLeadingWildcard: false # 推荐禁用
建议: 设置为 false。防止性能问题和 DoS 攻击。
开发环境 #
indices:
query:
query_string:
allowLeadingWildcard: true # 允许使用
建议: 保持 true。开发环境需要灵活性。
特定业务需求 #
indices:
query:
query_string:
allowLeadingWildcard: true
建议: 仅在确实需要前导通配符时使用,并监控查询性能。
代码示例 #
easysearch.yml 基础配置 #
indices:
query:
query_string:
allowLeadingWildcard: true
禁用前导通配符(推荐) #
indices:
query:
query_string:
allowLeadingWildcard: false
完整查询配置 #
indices:
query:
query_string:
allowLeadingWildcard: false
analyze_wildcard: true
动态更新配置 #
PUT /_cluster/settings
{
"transient": {
"indices.query.query_string.allowLeadingWildcard": false
}
}
相关配置 #
| 配置项 | 作用 | 默认值 |
|---|---|---|
indices.query.query_string.allowLeadingWildcard | 是否允许前导通配符 | true |
indices.query.query_string.analyze_wildcard | 是否分析通配符 | true |
查询示例 #
允许前导通配符 #
GET /_search
{
"query": {
"query_string": {
"query": "*product" // 前导通配符
}
}
}
禁用后会被拒绝 #
GET /_search
{
"query": {
"query_string": {
"query": "*product"
}
}
}
// 错误: leading wildcard is not allowed
推荐的替代方案 #
// 使用前缀查询
GET /_search
{
"query": {
"prefix": {
"field": "name",
"value": "prod"
}
}
}
// 使用后缀通配符
GET /_search
{
"query": {
"query_string": {
"query": "product*"
}
}
}
性能影响分析 #
| allowLeadingWildcard 设置 | 优点 | 缺点 |
|---|---|---|
| true(默认) | 灵活查询 | 性能风险、DoS 风险 |
| false | 防止慢查询 | 限制查询灵活性 |
查询性能对比 #
查询性能对比
查询: *term
allowLeadingWildcard = true:
耗时: 10-30 秒(全索引扫描)
CPU: 高
磁盘: 高
allowLeadingWildcard = false:
耗时: 拒绝查询
CPU: 无
磁盘: 无
替代方案: term*
耗时: 10-50 毫秒(使用索引)
CPU: 低
磁盘: 低
安全考虑 #
DoS 攻击防护
恶意用户可能:
├── 发送大量前导通配符查询
├── 每个查询触发全索引扫描
├── 消耗大量 CPU 和磁盘 I/O
└── 导致服务不可用
防护措施:
├── 设置 allowLeadingWildcard = false
├── 限制慢查询的执行时间
├── 使用查询熔断器
└── 监控异常查询模式
使用场景 #
推荐禁用的场景 #
- 生产环境: 防止性能问题和 DoS 攻击
- 公开 API: 外部用户可访问的 API
- 大数据量: 索引数据量很大
- 性能敏感: 对查询性能要求高
推荐启用的场景 #
- 内部工具: 内部管理工具
- 小数据集: 数据量很小的场景
- 受控环境: 用户可信任的环境
- 特殊需求: 确实需要前导通配符
替代方案 #
前导通配符的替代方案
1. 前缀查询 (Prefix Query)
GET /_search
{
"query": {
"prefix": {
"field": "name",
"value": "prod"
}
}
}
适用: 搜索以特定字符串开头的文档
2. 后缀通配符
GET /_search
{
"query": {
"query_string": {
"query": "product*"
}
}
}
适用: 搜索以特定字符串结尾的文档
3. 通配符查询 (Wildcard Query)
GET /_search
{
"query": {
"wildcard": {
"field": "name",
"value": "prod*"
}
}
}
适用: 更灵活的模式匹配
4. 反向索引 + ngram
索引时: 反转词语并使用 ngram
查询时: 反转查询词
适用: 复杂模式匹配
注意事项 #
默认值: 默认值为
true,但生产环境建议禁用。性能影响: 前导通配符会导致全索引扫描,性能极差。
DoS 风险: 恶意用户可能利用此进行 DoS 攻击。
查询级别: 此配置在索引级别生效。
动态更新: 支持动态更新,修改后立即生效。
替代方案: 应该使用前缀查询或后缀通配符。
监控建议: 监控慢查询日志,发现前导通配符查询。
查询优化: 禁用后应优化查询语句,避免使用前导通配符。
用户教育: 教育用户避免使用前导通配符查询。
测试验证: 禁用后需要验证所有查询是否正常工作。





