我想使用ElasticSearch实现一个关键字黑名单。基本上,我想创建一个用户不允许搜索的禁用查询列表。然后我希望能够通过一个检查查询,看看它匹配哪些禁止查询(如果有的话)。
被检查的查询与被禁止的查询匹配,如果被禁止的查询有其关键字的子集。为了说明这一点,让我提供一个例子:
- 禁止查询:
- "黑色lives"
- "黑人的生命也重要";
- "黑人的生活matters"
- "黑人的命也是命">
- 已检查查询:"黑人生活"matter"
- 匹配:
- "黑色lives"
- "黑人的生命也重要";
只有前两个禁止查询匹配,因为它们是被检查查询的严格子集。第三个被禁止的查询不匹配,因为它使用"matter"而不是"matter"。最后一个被禁止的查询不匹配,因为它不是"黑人生命重要"的严格子集,因为它有一个额外的关键字"rulez"。
有人告诉我,实现这一点的最好方法是一个渗透索引。我的问题是,如何创建一个渗透查询,实现针对已检查查询(传入文档)的子集匹配?
这是关于渗透查询的文档页面:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-percolate-query.html
这是一个关于子集匹配的相关答案:https://discuss.elastic.co/t/subset-in-an-array/237459
实现用例的最佳方法是使用Percolate查询
添加包含索引数据、映射、搜索查询和搜索结果的工作示例
指数映射:
{
"mappings": {
"properties": {
"field": {
"type": "text"
},
"query": {
"type": "percolator"
}
}
}
}
索引数据:
{
"query": {
"match": {
"field": {
"query": "black lives matter rulez",
"operator": "AND"
}
}
}
}
{
"query": {
"match": {
"field": {
"query": "black lives matters",
"operator": "AND"
}
}
}
}
{
"query": {
"match": {
"field": {
"query": "black lives matter",
"operator": "AND"
}
}
}
}
{
"query": {
"match": {
"field": {
"query": "black lives",
"operator": "AND"
}
}
}
}
搜索查询:
{
"query": {
"percolate": {
"field": "query",
"document": {
"field": "black lives matter"
}
}
}
}
搜索结果:
"hits": [
{
"_index": "68734373",
"_type": "_doc",
"_id": "2",
"_score": 0.39229372,
"_source": {
"query": {
"match": {
"field": {
"query": "black lives matter",
"operator": "AND"
}
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
}
},
{
"_index": "68734373",
"_type": "_doc",
"_id": "1",
"_score": 0.26152915,
"_source": {
"query": {
"match": {
"field": {
"query": "black lives",
"operator": "AND"
}
}
}
},
"fields": {
"_percolator_document_slot": [
0
]
}
}
]