匹配规则

Rules 规则引擎 #

Rules 插件是 EasySearch 的规则匹配引擎,可在数据写入时自动匹配规则库,为文档添加标签字段,实现高效的内容分类、审核和标注。

功能特性 #

  • 实时匹配:数据写入时自动匹配规则,无需后处理
  • 高性能:基于优化的 C++ 规则引擎,支持复杂规则和大规则库
  • 灵活配置:支持自定义字段、正则表达式、数值范围匹配
  • 多规则匹配:一条文档可匹配多个规则,所有标签保留到数组中
  • 集群广播:多节点环境自动编译规则到所有规则插件节点

基本概念 #

规则库 (Repository) #

规则库是规则的集合,每个规则库有唯一的 repo_id,存储在 .match_rules 索引中。

规则 (Rule) #

规则由表达式描述组成:

expression\t#offset#description
  • expression: 匹配表达式(支持 AND/OR/NOT、正则、范围等)
  • offset: 规则序号(从 0 开始,系统自动生成,用于区分不同规则)
  • description: 规则描述(匹配时作为标签返回)

重要说明

  • offset 是导入到规则索引后系统自动生成的,本身没有业务含义
  • 通过 _import API 导入规则时不需要手动指定 offset
  • 导入时只需提供 expressiondescription,系统会自动分配 offset

标签 (Tag) #

文档匹配规则后,规则的 #offset#description 会添加到文档的 tags 字段。


环境要求 #

节点配置 #

Rules 插件依赖 native 库(C++ 编译的规则引擎),需要在 config/easysearch.yml 中禁用系统调用过滤器:

bootstrap.system_call_filter: false

为什么需要这个配置?

  • Rules 插件需要调用 JNI 和 native 库(libruledb-r.so)
  • 规则编译过程会执行系统调用(如 fork、exec 等)
  • EasySearch 默认启用的 seccomp 过滤器会阻止这些操作

注意:禁用此过滤器会降低一定的安全性,建议只在运行 rules 插件的节点上禁用。


快速开始 #

步骤 1: 导入规则 #

使用 POST /_match_rules/{repo_id}/_import 导入规则到索引:

POST /_match_rules/security_v1/_import
{
  "name": "安全规则库",
  "description": "用于安全事件分类的规则库",
  "tags": ["security", "content-filter"],
  "rules": [
    {
      "expression": "枪 or 手枪 or 步枪 or 猎枪",
      "description": "涉枪武器关键词"
    },
    {
      "expression": "AK47 or AK-47 or M16 or M4A1",
      "description": "枪支型号"
    },
    {
      "expression": "海洛因 or 冰毒 or 摇头丸 or K粉",
      "description": "毒品名称"
    }
  ]
}

响应

{
  "success": true,
  "message": "Successfully imported 3 rules to repo_id 'security_v1' (version: 1)",
  "repo_id": "security_v1",
  "version": "1",
  "rule_count": 3
}

步骤 2: 编译规则库 #

使用 POST /_match_rules/{repo_id}/_compile 编译规则为二进制库:

POST /_match_rules/security_v1/_compile
{
  "quiet": true
}

响应

{
  "success": true,
  "message": "Successfully compiled 3 rules to /path/to/output/security_v1",
  "result": {
    "database_path": "/path/to/output/security_v1",
    "duration_ms": 1250,
    "total_rules": 3
  }
}

步骤 3: 创建 Ingest Pipeline #

PUT _ingest/pipeline/security-check
{
  "description": "使用规则引擎对安全事件分类",
  "processors": [
    {
      "check_match_rules": {
        "id": "security_v1"
      }
    }
  ]
}

使用自定义目标字段

PUT _ingest/pipeline/security-check-custom
{
  "description": "使用规则引擎对安全事件分类,结果写入 security_labels 字段",
  "processors": [
    {
      "check_match_rules": {
        "id": "security_v1",
        "target_field": "security_labels"
      }
    }
  ]
}

配置参数

参数类型必需默认值说明
idstring-规则库 ID(对应 repo_id)
target_fieldstring“tags”匹配结果写入的目标字段名
ignore_missingbooleanfalse是否忽略缺失字段错误
regex_start_at_wordbooleantrue正则是否从单词边界开始
fieldsarray[]数值字段列表(用于范围匹配,必须与编译时声明的字段一致)
default_match_fieldstring“content”默认匹配字段名(未声明字段按此字段处理),暂时只支持 “content” 字段

步骤 4: 写入文档测试 #

POST security-events/_doc?pipeline=security-check
{
  "title": "枪支交易案",
  "content": "网上出售手枪,价格5000元",
  "timestamp": "2025-12-31T10:00:00Z"
}

查询结果

{
  "_source": {
    "title": "枪支交易案",
    "content": "网上出售手枪,价格5000元",
    "timestamp": "2025-12-31T10:00:00Z",
    "tags": ["#0#涉枪武器关键词"]
  }
}

规则语法 #

规则文件格式 #

规则文件是文本文件,每行一条规则,在系统中存储的格式如下:

expression\t#offset#description

格式说明

  • expression: 规则表达式(匹配条件)
  • #offset#: 规则序号(从 0 开始,由系统自动生成)
  • description: 规则描述(匹配时作为标签返回)

导入时格式:通过 _import API 导入时,只需提供 expressiondescription,系统会自动生成 offset:

{
  "expression": "枪 or 手枪 or 步枪",
  "description": "涉枪武器关键词"
}

系统存储示例(导入后在 .match_rules 索引中的格式):

枪 or 手枪 or 步枪	#0#涉枪武器关键词
AK47 or AK-47 or M16	#1#枪支型号
海洛因 or 冰毒 or 摇头丸	#2#毒品名称

注意

  • # 开头的行是注释
  • 空行会被跳过
  • 可使用 \\ 作为续行符将长规则分成多行
  • 表达式和描述之间使用 Tab 键分隔(\t

基本语法 #

1. 逻辑操作符 #

操作符别名优先级说明
and&同时满足(逻辑与)
or\|满足任一(逻辑或)
not&!, -中(二元)/最高(一元)不包含(逻辑非)
near距离匹配

示例

# AND: 同时包含两个词
中国 and 人民

# OR: 包含任一词
中国 or 人民

# NOT: 包含前者但不包含后者
中国 and not 日本
中国 not 日本
中国 - 日本

2. 关键词匹配 #

枪 or 手枪 or 步枪

匹配包含任一关键词的文档。

⚠️ 特殊字符警告:减号 - 的特殊含义

减号 -not 操作符的别名,会被解释为逻辑非。如果要匹配包含减号的字面文本,必须用引号括起来

# ❌ 错误:会被解释为"包含中国 AND 不包含2025年GDP"
中国-2025年GDP

# ✅ 正确:匹配字面文本"中国-2025年GDP"
"中国-2025年GDP"

# ❌ 错误:会被解释为"包含高端 AND 不包含低端"
高端-低端产品

# ✅ 正确:匹配字面文本"高端-低端产品"
"高端-低端产品"

其他需要加引号的场景

  • 包含空格:"紧急 通知"
  • 包含特殊符号:"C++编程", "@用户名"
  • 包含操作符关键字:"and或or"

3. 字段限定 #

语法

  • fieldname(expression): 子串匹配,在指定字段的任意位置匹配表达式
  • fieldname[expression]: 全匹配,表达式必须匹配字段的全部内容

示例

# 在 title 字段中查找"紧急"
title(紧急)

# 在 author 字段中查找"张三"
author(张三)

# 组合使用
title(紧急) and content(通知) and category(安全)

# 全匹配(用于精确匹配)
status[已审核]

字段处理机制

规则引擎对字段的处理遵循以下规则:

  1. 默认字段titlecontent 是系统内置字段,无需声明

    • 未指定字段的表达式默认匹配 content 字段
  2. 未声明字段的处理:文档中未在编译时声明的字段,会被当作 content 字段处理

    • 例如:author(张三) 中的 author 如果未声明,会按 content 字段匹配
  3. 数值字段:用于范围匹配的数值字段(如 range(100, 500)必须在编译时通过 fields 参数声明

    • 未声明的数值字段会导致编译失败

字段声明示例

# 编译时声明数值字段
POST /_match_rules/repo/_compile
{
  "fields": ["range", "price", "ram_gb"]
}

# 规则中使用
{
  "expression": "title(手机) and price(3000, 5000)"
}

4. 正则表达式 #

简单正则(用 {{...}} 括起来):

# 匹配北京电话号码
{{(\(010\)|010)-?[0-9]{8}}}

# 匹配邮箱地址
{{\w+@\w+\.\w+}}

复合正则(用 [...] 括起来,支持逻辑运算):

# 匹配除 .com 外的所有网站
[{{https?://([\w\d_-]+\.)+[\w\d_-]+}} and not {{.*\.com}}]

# 字段中使用正则
author({{张.*}})

重要:正则表达式必须用双引号包围。

❌ 错误:author(/张.*/) ✅ 正确:author("/张.*/")

高级功能 #

距离匹配 (near) #

near 用于匹配两个词之间的距离。

语法

  • A near/num B: A 和 B 之间距离不超过 num(不分前后)
  • A near/+num B: A 在 B 之前,距离不超过 num
  • A near/-num B: A 在 B 之后,距离不超过 num

距离单位

  • 中文:每个汉字为 1 个单位
  • 英文/数字:每个单词为 1 个单位(如 computer10086varname_123 均为 1 个单位)

示例

# "中国"和"人民"之间距离不超过 3
中国 near/3 人民

# "中国"必须在"人民"之前,距离不超过 5
中国 near/+5 人民

# 链式 near(等价于多个 near 的 and)
中国 near/3 人民 near/5 勤劳 near/7 勇敢

复合 near

(中国 or 中华 or 华夏) near/3 (人民 or 百姓) near/5 (勤劳 or 勤奋)

数值范围匹配 #

range(400, 600)
price(1000, 5000)

匹配数值在指定范围内的文档(闭区间 [min, max])。

要求

  1. 字段类型必须是数值
  2. 编译时必须声明字段名(使用 fields 参数)

示例

POST /_match_rules/opinion_check/_import
{
  "rules": [
    {
      "expression": "title(威马M5) and content(续航) and range(0, 500)",
      "description": "威马M5续航不足"
    }
  ]
}

POST /_match_rules/opinion_check/_compile
{
  "fields": ["range", "price"]
}

规则编写最佳实践 #

1. 从简单到复杂 #

# 简单规则
枪 or 手枪

# 中等复杂度
title(枪支) and (买卖 or 交易 or 出售)

# 复杂规则
(枪 or 手枪 or 步枪) near/5 (买 or 卖 or 交易) and not (玩具 or 模型)

2. 合理使用字段限定 #

# 标题匹配更精准
title(紧急通知)

# 组合多个字段
title(安全) and content(漏洞) and author(安全团队)

3. 使用 near 提高精确度 #

# 简单 OR 可能误匹配
枪支 or 交易

# 使用 near 限制距离
枪支 near/10 交易

4. 善用 NOT 排除干扰 #

# 排除玩具枪
(枪 or 手枪) and not (玩具 or 模型 or 仿真)

5. 正则表达式用于模糊匹配 #

# 匹配所有以"张"开头的姓名
author({{张.*}})

# 匹配手机号
{{1[3-9][0-9]{9}}}

常见错误 #

❌ 错误 1: 减号未加引号导致误解析 #

# 错误:会被解释为 NOT 操作
title(2024-2025年报)
# 实际匹配:title 包含"2024"但不包含"2025年报"

# 正确:匹配字面文本
title("2024-2025年报")

常见场景

  • 日期范围:"2024-01-01", "2024-2025"
  • 产品型号:"iPhone-15", "GTX-4090"
  • 复合词:"高端-低端", "线上-线下"

❌ 错误 2: 正则未加引号 #

# 错误
author(/张.*/)

# 正确
author("/张.*/")

❌ 错误 3: 忘记声明自定义字段 #

// 规则中使用了 range 字段
"expression": "range(100, 500)"

// 但编译时忘记声明
POST /_match_rules/repo/_compile
{
  //  缺少 fields 参数
}

//  正确做法
POST /_match_rules/repo/_compile
{
  "fields": ["range"]
}

❌ 错误 4: 表达式和描述未用 Tab 分隔 #

# 错误(使用空格)
枪 or 手枪 涉枪内容

# 正确(使用 Tab)
枪 or 手枪	涉枪内容

特殊字符速查表 #

字符在规则中的含义如何匹配字面值示例
-NOT 操作符用引号括起来"2024-2025"
&AND 操作符用引号括起来"Tom&Jerry"
\|OR 操作符用引号括起来"A\|B"
( )分组、字段限定用引号括起来"(重要)"
[ ]全匹配、复合正则用引号括起来"[TODO]"
{ }正则表达式用引号括起来"{变量}"
空格词分隔符用引号括起来"hello world"

建议:当规则包含任何可能引起歧义的字符时,养成加引号的习惯。


高级应用示例 #

示例 1: 舆情监控 #

使用数值范围匹配来监控产品评价中的数值异常。

导入规则

POST /_match_rules/opinion_check/_import
{
  "name": "舆情监控规则",
  "rules": [
    {
      "expression": "title(威马M5) and content(续航) and range(0, 500)",
      "description": "威马M5续航不足"
    },
    {
      "expression": "title(威马M7) and content(续航) and range(2500, 9999)",
      "description": "威马M7续航异常高"
    }
  ]
}

编译时声明字段

POST /_match_rules/opinion_check/_compile
{
  "fields": ["range", "price", "energy_kwh"],
  "quiet": true
}

说明:编译时只需声明规则中实际使用的数值字段。上述规则中使用了 range(0, 500)price(2500, 9999),所以声明了这两个字段。

Pipeline 配置

PUT _ingest/pipeline/opinion_check
{
  "description": "使用规则引擎监测商家网络舆情",
  "processors": [
    {
      "check_match_rules": {
        "id": "opinion_check",
        "fields": [
          "range",
          "price",
          "energy_kwh",
          "fuel_lper100km",
          "ram_gb",
          "storage_gb",
          "volume_ml",
          "concentration"
        ]
      }
    }
  ]
}

说明:Pipeline 中的 fields 参数可以包含更多数值字段,以便支持文档中可能出现的其他数值字段匹配。这些字段不需要在当前规则库中使用,但如果文档包含这些字段,规则引擎会正确处理。

测试匹配

POST /_ingest/pipeline/opinion_check/_simulate
{
  "docs": [
    {
      "_index": "reviews",
      "_id": "doc_1",
      "_source": {
        "title": "威马M5续航测试",
        "content": "威马M5的续航表现一般,实测续航里程偏低",
        "range": 450
      }
    },
    {
      "_index": "reviews",
      "_id": "doc_2",
      "_source": {
        "title": "威马M7续航表现",
        "content": "威马M7的续航非常出色",
        "range": 2650
      }
    }
  ]
}

预期结果

{
  "docs": [
    {
      "doc": {
        "_source": {
          "title": "威马M5续航测试",
          "content": "威马M5的续航表现一般,实测续航里程偏低",
          "range": 450,
          "tags": ["#0#威马M5续航不足"]
        }
      }
    },
    {
      "doc": {
        "_source": {
          "title": "威马M7续航表现",
          "content": "威马M7的续航非常出色",
          "range": 2650,
          "tags": ["#1#威马M7续航异常高"]
        }
      }
    }
  ]
}

规则索引结构 #

.match_rules 索引说明 #

.match_rules 是一个隐藏的系统索引,用于存储规则库的元数据和配置信息。每个规则库对应索引中的一条文档。

索引特性

  • 索引名称.match_rules(以 . 开头的隐藏索引)
  • 分片配置:1 个主分片,1 个副本
  • 自动扩展:副本数自动扩展到 0-1
  • 文档 ID:使用 repo_id 作为文档 ID

核心字段

字段类型必需说明
nametext规则库名称
descriptiontext规则库描述
tagskeyword[]规则库标签(用于分类)
rulestext规则文本内容(格式:expression\t#offset#description
versionkeyword规则库版本(自动递增:1, 2, 3…)
statuskeyword编译状态:pending/compiled/partial/failed
total_rulesinteger规则总数
compiled_atdate编译完成时间
compiled_nodeskeyword[]已编译节点列表
error_messagetext错误信息(编译失败时)
createddate创建时间
updateddate更新时间

规则文本格式

rules 字段存储完整的规则定义,每行一条规则,包含自动生成的 offset:

expression\t#offset#description

其中:

  • offset 是系统自动生成的规则序号(从 0 开始)
  • 通过 _import API 导入时不需要手动指定 offset

示例:

枪 or 手枪 or 步枪\t#0#涉枪武器关键词
AK47 or AK-47 or M16\t#1#枪支型号
海洛因 or 冰毒\t#2#毒品名称

查询示例

# 查询单个规则库(排除 rules 字段避免大量数据)
GET .match_rules/_doc/security_v1?_source_excludes=rules

# 搜索所有已编译的规则库
GET .match_rules/_search
{
  "query": {
    "term": {
      "status": "compiled"
    }
  },
  "_source": {
    "excludes": ["rules"]
  }
}

# 查询特定标签的规则库
GET .match_rules/_search
{
  "query": {
    "term": {
      "tags": "security"
    }
  }
}

API 参考 #

导入规则 API #

POST /_match_rules/{repo_id}/_import #

覆盖导入(删除旧规则,创建新规则)。

请求体

{
  "name": "规则库名称",
  "description": "规则库描述",
  "tags": ["tag1", "tag2"],
  "rules": [
    {
      "expression": "规则表达式",
      "description": "规则描述"
    }
  ]
}

PUT /_match_rules/{repo_id}/_import #

追加导入(保留旧规则,添加新规则)。

示例

PUT /_match_rules/security_v1/_import
{
  "rules": [
    {
      "expression": "买枪 or 卖枪 or 枪支交易",
      "description": "武器交易"
    }
  ]
}

响应

{
  "success": true,
  "message": "Successfully imported 4 rules to repo_id 'security_v1' (version: 2)",
  "repo_id": "security_v1",
  "version": "2",
  "rule_count": 4
}

POST /_match_rules/_import #

自动生成 repo_id(格式:repo_{timestamp})。

编译规则 API #

POST /_match_rules/{repo_id}/_compile #

编译规则库为二进制格式。

请求体

{
  "fields": ["author", "source", "range"],
  "quiet": true
}

参数说明

参数类型必需默认值说明
fieldsarray[]数值字段列表(用于范围匹配,如 range, price 等)。注意titlecontent 是默认字段,无需声明;未声明的非数值字段会被当作 content 处理
quietbooleantrue是否静默模式(不输出详细日志)

多节点集群:编译会自动广播到所有包含规则插件的节点,确保每个规则插件节点都有规则库文件。

响应

{
  "success": true,
  "message": "Broadcast compile completed for 3 nodes:\n  ✓ node-1: 15000 rules (2500ms)\n  ✓ node-2: 15000 rules (2480ms)\n  ✓ node-3: 15000 rules (2520ms)",
  "result": {
    "database_path": "/path/to/output/opinion_check",
    "duration_ms": 2520,
    "total_rules": 15000
  }
}

查询规则库 API #

GET .match_rules/_doc/{repo_id} #

查询规则库详情。

GET .match_rules/_doc/security_v1

响应

{
  "_index": ".match_rules",
  "_id": "security_v1",
  "_version": 2,
  "found": true,
  "_source": {
    "name": "安全规则库",
    "description": "用于安全事件分类的规则库",
    "tags": ["security", "content-filter"],
    "rules": "枪 or 手枪 or 步枪 or 猎枪\t#0#涉枪武器关键词\nAK47 or AK-47 or M16 or M4A1\t#1#枪支型号\n...",
    "version": "2",
    "status": "compiled",
    "compiled_at": "2026-01-07T08:00:00Z",
    "total_rules": 4,
    "compiled_nodes": ["node-1", "node-2", "node-3"],
    "created": "2025-12-31T10:00:00Z",
    "updated": "2025-12-31T10:15:00Z"
  }
}

字段说明

.match_rules 索引用于存储规则库的元数据和配置信息。每个规则库对应一条文档,文档 ID 即为 repo_id

字段类型说明
nametext规则库名称(用户自定义,用于标识规则库用途)
descriptiontext规则库描述(详细说明规则库的作用和使用场景)
tagskeyword[]规则库标签(用于分类和检索,如 [“security”, “content-filter”])
rulestext规则文本内容(完整的规则定义,每行一条规则,格式:expression\t#offset#description
versionkeyword规则库版本(每次导入递增,格式:1, 2, 3…)
statuskeyword编译状态:pending(待编译)、compiled(已编译)、partial(部分编译)、failed(失败)
total_rulesinteger规则总数(导入的规则条数)
compiled_atdate编译完成时间(最后一次成功编译的时间戳)
compiled_nodeskeyword[]已编译节点列表(已成功编译此规则库的节点名称)
error_messagetext错误信息(编译失败时的详细错误描述)
createddate创建时间(规则库首次导入的时间)
updateddate更新时间(规则库最后一次修改的时间)

注意

  • rules 字段可能包含大量文本(数万条规则),查询时建议使用 _source_excludes=rules 排除此字段
  • version 字段在每次使用 POST /_match_rules/{repo_id}/_import(覆盖模式)或 PUT /_match_rules/{repo_id}/_import(追加模式)导入时自动递增
  • compiled_nodes 字段在多节点集群中记录了所有成功编译的节点,用于判断集群同步状态

节点启动与规则同步 #

自动同步机制 #

节点启动时,Rules 插件会自动检查并同步缺失的规则库:

  1. 检查本地规则库:对比 .match_rules 索引中的规则库
  2. 自动编译缺失库:对于本地不存在的规则库,自动执行编译
  3. 更新节点状态:同步完成后更新 compiled_nodes 列表

预期行为

  • 首次启动:自动编译所有规则库(通常 10-20 秒)
  • 集群重启:验证本地规则库,如有缺失自动恢复
  • 新节点加入:后台静默同步,不影响集群服务

同步期间的写入行为 #

在规则库同步期间,写入操作会延迟等待,直到同步完成后自动成功。

用户体验

  • 写入请求不会立即失败,而是等待同步完成
  • 等待时间取决于规则库大小(通常几秒到几分钟)
  • 同步完成后写入自动成功,无需重新提交

不受影响的操作

  • ✅ 所有读操作(查询、获取文档等)
  • ✅ 系统索引的写入(.match_rules 等)

预计等待时间

  • 通常 10-20 秒
  • 大型规则库(数万条)可能需要更长时间

批量导入工具 #

对于大规则文件,可使用 Python 脚本批量导入:

# 基本用法(追加模式)
python import_rules.py -f rules.txt -r security_v1 -n "安全规则库"

# 覆盖模式(删除旧规则)
python import_rules.py -f rules.txt -r opinion_v9 -n "舆情规则库" --overwrite

# 指定名称、描述和标签
python import_rules.py -f rules.txt -r opinion_v9 \
  -n "舆情监控规则" \
  -d "用于舆情监控的规则库" \
  -t opinion -t monitoring

# 使用 HTTPS 和自定义认证
python import_rules.py -f rules.txt -r security_v1 -n "安全规则" \
  --url https://localhost:9200 \
  --username admin \
  --password admin123

规则文件格式 (rules.txt):

规则文件每行一条规则,使用 Tab 键分隔表达式和描述(不需要手动指定 offset):

枪 or 手枪 or 步枪	涉枪武器关键词
AK47 or AK-47 or M16	枪支型号
海洛因 or 冰毒	毒品名称

说明:导入时系统会自动为每条规则生成 offset(从 0 开始),无需手动添加 #offset# 部分。

工具位置plugins/rules/src/test/resources/import_rules.py


使用场景 #

1. 内容安全审核 #

规则示例

{
  "rules": [
    {
      "expression": "枪 or 手枪 or 步枪 or 猎枪",
      "description": "涉枪内容"
    },
    {
      "expression": "海洛因 or 冰毒 or 摇头丸",
      "description": "涉毒内容"
    },
    {
      "expression": "isis or 伊斯兰国 or IS组织",
      "description": "恐怖组织"
    }
  ]
}

查询示例

GET security-events/_search
{
  "query": {
    "terms": {
      "tags": ["#0#涉枪内容", "#1#涉毒内容"]
    }
  }
}

2. 新闻分类 #

规则示例

{
  "rules": [
    {
      "expression": "author(张三) and source(新华网)",
      "description": "张三_新华网"
    },
    {
      "expression": "title(紧急) and content(通知) and category(安全)",
      "description": "紧急安全通知"
    }
  ]
}

3. 商品推荐 #

规则示例

{
  "rules": [
    {
      "expression": "category(手机) and price(3000, 5000)",
      "description": "中端手机"
    },
    {
      "expression": "category(笔记本) and ram_gb(16, 32)",
      "description": "高性能笔记本"
    }
  ]
}

4. 舆情监控 #

规则示例(见上文"数值范围匹配"章节)


性能优化 #

规则库大小建议 #

  • 单个规则库不超过 50,000 条规则
  • 大规则库考虑拆分为多个 repo_id

编译性能参考 #

规则数编译耗时
1,000~100-200ms
10,000~500-1000ms
100,000~5-10s

字段优化 #

  • 只声明规则中实际使用的字段
  • 数值字段(如 rangeprice)必须声明,否则编译失败

常见问题 #

Q1: tags 字段为空? #

可能原因

  1. 规则未匹配到内容
  2. 规则库路径不正确
  3. 自定义字段未声明

排查步骤

  1. 使用 _simulate API 测试 pipeline
  2. 检查规则表达式是否正确
  3. 确认编译时是否声明了 fields 参数
POST _ingest/pipeline/security-check/_simulate
{
  "docs": [
    {
      "_source": {
        "title": "测试",
        "content": "手枪交易"
      }
    }
  ]
}

Q2: 编译失败? #

可能原因

  1. 规则语法错误
  2. 索引中无规则数据
  3. 自定义字段未声明(导致 Range error)
  4. 未设置 bootstrap.system_call_filter: false

排查步骤

  1. 首先检查节点配置:确认 config/easysearch.yml 中设置了 bootstrap.system_call_filter: false
  2. 检查编译响应中的 message 字段
  3. 确认 .match_rules 索引中有数据:GET .match_rules/_doc/{repo_id}
  4. 检查是否声明了数值字段
  5. 查看 EasySearch 日志中的详细错误信息

Q3: 正则表达式报错? #

错误信息literal start with punct must be quoted

原因:正则表达式未用双引号包围。

解决: ❌ 错误:author(/张.*/) ✅ 正确:author("/张.*/")

Q4: Pipeline 不生效? #

排查步骤

  1. 检查 Pipeline 是否正确创建:GET _ingest/pipeline/security-check
  2. 确认规则库已编译:检查 status 字段
  3. 查看 EasySearch 日志:logs/easysearch.log

Q5: 节点启动后写入操作变慢? #

现象:节点重启后,写入操作响应时间变长。

原因:这是正常的自动同步机制,节点启动时会自动检查并同步缺失的规则库。

解决方案

  • 等待同步完成(通常 10-20 秒)
  • 如需减少等待时间,可在重启前手动触发规则编译
  • 多节点集群中,新节点加入不会影响其他节点的写入性能

Q6: 规则库文件丢失后怎么办? #

现象:规则库文件被误删或磁盘故障导致文件丢失。

自动恢复机制

  • 插件使用元数据文件(.compiled_repos.json)记录编译历史
  • 节点启动时检测到文件丢失,会自动从 .match_rules 索引重新编译
  • 同步期间写入操作会等待,完成后自动恢复

手动恢复(如自动恢复失败):

# 1. 检查规则库是否在索引中
GET .match_rules/_doc/{repo_id}

# 2. 重新编译
POST /_match_rules/{repo_id}/_compile

限制和注意事项 #

  1. License 要求:需要启用 rule-engine 特性的有效 License
  2. 系统配置要求:必须设置 bootstrap.system_call_filter: false(见"环境要求"章节)
  3. 目标字段可配置:默认写入 tags 字段,可通过 target_field 参数自定义
  4. 数值字段类型:数值范围匹配要求字段值为数值类型
  5. 正则语法:必须使用双引号包围正则表达式
  6. 编译依赖索引:编译前必须先导入规则到 .match_rules 索引
  7. 节点启动同步:节点启动时会自动同步规则库,写入操作会等待同步完成(通常 10-20 秒)
  8. 元数据文件.compiled_repos.json 用于检测文件丢失,请勿手动删除

参考资料 #

  • 规则语法文档plugins/rules/ruledb-pkg/README.md
  • 测试指南plugins/rules/TESTING.md
  • 广播编译设计plugins/rules/BROADCAST_COMPILE_DESIGN.md
  • 导入工具plugins/rules/src/test/resources/import_rules.py