用于动态定义的正则表达式搜索的弹性搜索分析器
Elastic Search Analyzer for Dynamically Defined Regular Expression Searches
我们在弹性搜索索引中有很多文档,目前正在进行全文搜索。我在项目中的下一个要求是在文档中查找所有信用卡数据。将来用户还可以动态定义一些正则表达式搜索规则。但是使用标准分析器,不可能搜索信用卡信息或任何用户定义的规则。
例如,假设一个文档包含信用卡信息,例如 4321-4321-4321-4321 或 4321 4321 4321 4321。Elastic 搜索将该数据索引为 4 个部分,如下所示:
"tokens" : [
{
"token" : "4321",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<NUM>",
"position" : 0
},
{
"token" : "4321",
"start_offset" : 5,
"end_offset" : 9,
"type" : "<NUM>",
"position" : 1
},
{
"token" : "4321",
"start_offset" : 10,
"end_offset" : 14,
"type" : "<NUM>",
"position" : 2
},
{
"token" : "4321",
"start_offset" : 15,
"end_offset" : 19,
"type" : "<NUM>",
"position" : 3
}
]
我现在只是不考虑 Luhm 算法。如果我使用 reg exp "([0-9]{4}[- ]){3}[0-9]{4}" 进行基本的正则表达式搜索以查找信用卡,它 returns 没什么,因为数据没有为此进行分析和索引。我想为此目的,我需要为正则表达式搜索定义一个自定义分析器,并将另一个版本的数据存储在另一个字段或索引中。但正如我之前所说,将来用户将定义 his/her 自己的自定义搜索规则模式。我应该如何定义自定义分析器?我应该为此定义 ngram tokenizer(min:2, max:20) 吗?使用 ngram tokenizer 我想我可以搜索所有定义的正则表达式规则。但这合理吗?项目必须在没有任何性能问题的情况下处理大量数据。 (公司的整个文件系统都会被索引)。对于此类数据发现问题,您还有其他建议吗?我目前的主要目的是寻找信用卡。感谢您的帮助。
好的,这里有一对自定义分析器,可以帮助您检测信用卡号和社会保险号。随意调整正则表达式(通过 adding/removing 您将在数据中找到的其他字符分隔符)。
PUT test
{
"settings": {
"analysis": {
"analyzer": {
"card_analyzer": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"card_number"
]
},
"ssn_analyzer": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"social_number"
]
}
},
"filter": {
"card_number": {
"type": "pattern_replace",
"preserve_original": false,
"pattern": """.*(\d{4})[\s\.\-]+(\d{4})[\s\.\-]+(\d{4})[\s\.\-]+(\d{4}).*""",
"replacement": ""
},
"social_number": {
"type": "pattern_replace",
"preserve_original": false,
"pattern": """.*(\d{3})[\s\.\-]+(\d{2})[\s\.\-]+(\d{4}).*""",
"replacement": ""
}
}
}
},
"mappings": {
"properties": {
"text": {
"type": "text",
"fields": {
"card": {
"type": "text",
"analyzer": "card_analyzer"
},
"ssn": {
"type": "text",
"analyzer": "ssn_analyzer"
}
}
}
}
}
}
我们来测试一下。
POST test/_analyze
{
"analyzer": "card_analyzer",
"text": "Mr XYZ whose SSN is 442-23-1452 has a credit card whose number was 3526 4728 4723 6374"
}
将生成一个漂亮的纯数字信用卡号:
{
"tokens" : [
{
"token" : "3526472847236374",
"start_offset" : 0,
"end_offset" : 86,
"type" : "word",
"position" : 0
}
]
}
同样适用于 SSN:
POST test/_analyze
{
"analyzer": "ssn_analyzer",
"text": "Mr XYZ whose SSN is 442-23-1452 has a credit card whose number was 3526 4728 4723 6374"
}
将生成一个漂亮的纯数字社会安全号码:
{
"tokens" : [
{
"token" : "442231452",
"start_offset" : 0,
"end_offset" : 86,
"type" : "word",
"position" : 0
}
]
}
现在我们可以搜索信用卡或 SSN。假设我们有以下两个文件。 SSN 和信用卡号相同,但它们使用不同的字符分隔符
POST test/_doc
{ "text": "Mr XYZ whose SSN is 442-23-1452 has a credit card whose number was 3526 4728 4723 6374" }
POST test/_doc
{ "text": "SSN is 442.23.1452 belongs to Mr. XYZ. He paid via credit card number 3526-4728-4723-6374" }
您现在可以通过查找任何格式的信用卡号 and/or SSN 来找到这两个文件:
POST test/_search
{
"query": {
"match": {
"text.card": "3526 4728 4723 6374"
}
}
}
POST test/_search
{
"query": {
"match": {
"text.card": "3526 4728 4723-6374"
}
}
}
POST test/_search
{
"query": {
"match": {
"text.ssn": "442 23-1452"
}
}
}
以上所有查询都将匹配 return 两个文档。
我们在弹性搜索索引中有很多文档,目前正在进行全文搜索。我在项目中的下一个要求是在文档中查找所有信用卡数据。将来用户还可以动态定义一些正则表达式搜索规则。但是使用标准分析器,不可能搜索信用卡信息或任何用户定义的规则。 例如,假设一个文档包含信用卡信息,例如 4321-4321-4321-4321 或 4321 4321 4321 4321。Elastic 搜索将该数据索引为 4 个部分,如下所示:
"tokens" : [
{
"token" : "4321",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<NUM>",
"position" : 0
},
{
"token" : "4321",
"start_offset" : 5,
"end_offset" : 9,
"type" : "<NUM>",
"position" : 1
},
{
"token" : "4321",
"start_offset" : 10,
"end_offset" : 14,
"type" : "<NUM>",
"position" : 2
},
{
"token" : "4321",
"start_offset" : 15,
"end_offset" : 19,
"type" : "<NUM>",
"position" : 3
}
]
我现在只是不考虑 Luhm 算法。如果我使用 reg exp "([0-9]{4}[- ]){3}[0-9]{4}" 进行基本的正则表达式搜索以查找信用卡,它 returns 没什么,因为数据没有为此进行分析和索引。我想为此目的,我需要为正则表达式搜索定义一个自定义分析器,并将另一个版本的数据存储在另一个字段或索引中。但正如我之前所说,将来用户将定义 his/her 自己的自定义搜索规则模式。我应该如何定义自定义分析器?我应该为此定义 ngram tokenizer(min:2, max:20) 吗?使用 ngram tokenizer 我想我可以搜索所有定义的正则表达式规则。但这合理吗?项目必须在没有任何性能问题的情况下处理大量数据。 (公司的整个文件系统都会被索引)。对于此类数据发现问题,您还有其他建议吗?我目前的主要目的是寻找信用卡。感谢您的帮助。
好的,这里有一对自定义分析器,可以帮助您检测信用卡号和社会保险号。随意调整正则表达式(通过 adding/removing 您将在数据中找到的其他字符分隔符)。
PUT test
{
"settings": {
"analysis": {
"analyzer": {
"card_analyzer": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"card_number"
]
},
"ssn_analyzer": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase",
"social_number"
]
}
},
"filter": {
"card_number": {
"type": "pattern_replace",
"preserve_original": false,
"pattern": """.*(\d{4})[\s\.\-]+(\d{4})[\s\.\-]+(\d{4})[\s\.\-]+(\d{4}).*""",
"replacement": ""
},
"social_number": {
"type": "pattern_replace",
"preserve_original": false,
"pattern": """.*(\d{3})[\s\.\-]+(\d{2})[\s\.\-]+(\d{4}).*""",
"replacement": ""
}
}
}
},
"mappings": {
"properties": {
"text": {
"type": "text",
"fields": {
"card": {
"type": "text",
"analyzer": "card_analyzer"
},
"ssn": {
"type": "text",
"analyzer": "ssn_analyzer"
}
}
}
}
}
}
我们来测试一下。
POST test/_analyze
{
"analyzer": "card_analyzer",
"text": "Mr XYZ whose SSN is 442-23-1452 has a credit card whose number was 3526 4728 4723 6374"
}
将生成一个漂亮的纯数字信用卡号:
{
"tokens" : [
{
"token" : "3526472847236374",
"start_offset" : 0,
"end_offset" : 86,
"type" : "word",
"position" : 0
}
]
}
同样适用于 SSN:
POST test/_analyze
{
"analyzer": "ssn_analyzer",
"text": "Mr XYZ whose SSN is 442-23-1452 has a credit card whose number was 3526 4728 4723 6374"
}
将生成一个漂亮的纯数字社会安全号码:
{
"tokens" : [
{
"token" : "442231452",
"start_offset" : 0,
"end_offset" : 86,
"type" : "word",
"position" : 0
}
]
}
现在我们可以搜索信用卡或 SSN。假设我们有以下两个文件。 SSN 和信用卡号相同,但它们使用不同的字符分隔符
POST test/_doc
{ "text": "Mr XYZ whose SSN is 442-23-1452 has a credit card whose number was 3526 4728 4723 6374" }
POST test/_doc
{ "text": "SSN is 442.23.1452 belongs to Mr. XYZ. He paid via credit card number 3526-4728-4723-6374" }
您现在可以通过查找任何格式的信用卡号 and/or SSN 来找到这两个文件:
POST test/_search
{
"query": {
"match": {
"text.card": "3526 4728 4723 6374"
}
}
}
POST test/_search
{
"query": {
"match": {
"text.card": "3526 4728 4723-6374"
}
}
}
POST test/_search
{
"query": {
"match": {
"text.ssn": "442 23-1452"
}
}
}
以上所有查询都将匹配 return 两个文档。