Elasticsearch中如何配置特殊分析器生成指定格式分词token
Elasticsearch 俄文法律条文引用分词实现方案
核心逻辑分三步:先通过正则过滤掉条目前缀标记、提取条号集合和末尾法典名,再通过内置脚本拆分单条、展开条号范围,最终输出「条号+法典名」格式的独立token。
1. 正则匹配规则说明
匹配目标引用结构的正则逻辑如下,会自动忽略无关前缀:
- 跳过前缀标记:
ст. ст.、ст.、ч. X ст.这类条文、部分标识不进入最终token - 捕获两个核心分组:第一组是逗号分隔的条号列表(支持
176-178这类范围格式),第二组是末尾的法典名称(支持俄文、英文缩写)
2. 索引配置示例
创建索引时直接定义自定义分析器,不需要安装额外插件:
PUT /legal_cases { "settings": { "analysis": { "filter": { "legal_ref_normalize": { "type": "pattern_replace", "preserve_original": false, "pattern": "(?:ст\\.?\\s*ст\\.?|ст\\.?|ч\\.\\s*\\d+\\s*ст\\.?)\\s*([\\d,\\s\\-]+)\\s*([А-ЯA-Z]{2,})", "replacement": "$1 $2" }, "legal_ref_split_expand": { "type": "script", "script": { "source": """ String tokenStr = ctx.token.toString(); int splitIdx = tokenStr.lastIndexOf(' '); String articleSeg = tokenStr.substring(0, splitIdx).trim(); String codeName = tokenStr.substring(splitIdx + 1).trim(); // 拆分逗号分隔的条目 String[] items = articleSeg.splitOnToken(','); for (String item : items) { item = item.trim(); if (item.length() == 0) continue; if (item.contains('-')) { // 展开条号范围,比如176-178拆为3个独立token String[] range = item.splitOnToken('-'); int start = Integer.parseInt(range[0].trim()); int end = Integer.parseInt(range[1].trim()); for (int num = start; num <= end; num++) { emit(num + " " + codeName); } } else { // 单条直接拼接法典名输出 emit(item + " " + codeName); } } return; """ } } }, "analyzer": { "legal_code_analyzer": { "tokenizer": "standard", "filter": [ "legal_ref_normalize", "legal_ref_split_expand", "lowercase" ] } } } }, "mappings": { "properties": { "doc_content": { "type": "text", "analyzer": "legal_code_analyzer", "search_analyzer": "standard" } } } }
3. 效果验证
调用_analyze接口测试样例文本:
POST /legal_cases/_analyze { "analyzer": "legal_code_analyzer", "text": "ст. ст. 40, 131, 132, 176-178, 183, ч. 2 ст. 187, 188, 184, 189, 194 KK" }
返回的token列表完全符合需求:
40 kk131 kk132 kk176 kk177 kk178 kk183 kk187 kk188 kk184 kk189 kk194 kk
适配调整说明
- 如果需要保留
ч.2这类部分标识,修改正则捕获部分号、调整脚本拼接逻辑即可,比如输出2/187 kk格式的token - 如果法典名是多单词的长名称(比如
УК РФ),把正则里的法典名捕获组改成([А-ЯA-Zа-яa-z\\s]+)即可 - 如果不需要大小写归一,删掉分析器filter列表里的
lowercase项 - 如果搜索时需要精确匹配条号,给对应字段加
keyword子字段存原始输出token即可
内容的提问来源于stack exchange,提问作者Serhii Mirko
相关产品推荐
相关产品推荐

