如何在使用分析器搜索时排除星号

How to exclude asterisks while searching with analyzer

我需要按值数组进行搜索,每个值可以是简单的文本或带有 askterisks 的文本 (*)。 例如:

["MYULTRATEXT"]

我有下一个索引(我有一个很大的索引,所以我会简化它):

................
{
    "settings": {
         "analysis": {
            "char_filter": {
              "asterisk_remove": {
                "type": "pattern_replace",
                "pattern": "(\d+)*(?=\d)",
                "replacement": "1$"
              }
            },
            "analyzer": {
              "custom_search_analyzer": {
                "char_filter": [
                  "asterisk_remove"
                ],
                "type": "custom",
                "tokenizer": "keyword"
              }
            }
        }
    },
        "mappings": {
        "_doc": {
            "properties": {
               "name": {
                  "type": "text",
                  "analyzer":"keyword",
                  "search_analyzer": "custom_search_analyzer"
               },
     ......................

索引中的所有数据都用星号存储*例如:

curl -X PUT "localhost:9200/locations/_doc/2?pretty" -H 'Content-Type: application/json' -d'
{
   "name" : "MY*ULTRA*TEXT"
}

当我搜索这个字符串 MYULTRATEXT

时,我需要 return 完全相同的 name
curl -XPOST 'localhost:9200/locations/_search?pretty' -d '
{
  "query": { terms: { "name": ["MYULTRATEXT"] }  }
}'

它应该 return MY*ULTRA*TEXT,但它不起作用,因此找不到解决方法。有什么想法吗?

我尝试了 pattern_replace 但似乎我做错了什么或者我在这里遗漏了什么。

所以我需要在搜索时将所有 * 替换为空 ``

这可能对您有所帮助 - 您的正则表达式模式是问题所在。

您想将所有出现的 * 替换为 `` 下面的模式就可以解决问题..

PUT my_index
{
  "mappings": {
    "doc": {
      "properties": {
        "name": {
          "type": "text",
          "analyzer": "my_analyzer", 
          "search_analyzer":"my_analyzer"
        }
      }
    }
  },
  "settings": {
    "analysis": {
      "filter": {
        "asterisk_remove": {
          "type": "pattern_replace",
          "pattern": "(?<=\w)(\*)(?=\w)",
          "replacement": ""
        }
      },
      "analyzer": {
        "my_analyzer": {
          "filter": [
            "lowercase",
            "asterisk_remove"
          ],
          "type": "custom",
          "tokenizer": "keyword"
        }
      }
    }
  }
}

分析查询

POST my_index/_analyze
{
  "analyzer": "my_analyzer",
  "text": ["MY*ULTRA*TEXT"]
}

分析查询的结果

{
"tokens": [
    {
      "token": "myultratext",
      "start_offset": 0,
      "end_offset": 13,
      "type": "word",
      "position": 0
    }
  ]
}

Post一个文档

POST my_index/doc/1
{
  "name" : "MY*ULTRA*TEXT"
}

搜索查询

GET my_index/_search
{
  "query": {
    "match": {
      "name": "MYULTRATEXT"
    }
  }
}

GET my_index/_search
{
  "query": {
    "match": {
      "name": "myultratext"
    }
  }
}

结果搜索查询

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "my_index",
        "_type": "doc",
        "_id": "1",
        "_score": 0.2876821,
        "_source": {
          "name": "MY*ULTRA*TEXT"
        }
      }
    ]
  }
}

希望对您有所帮助

您提供的正则表达式和替换模式似乎有问题。

我想你想要的是:

            "char_filter": {
              "asterisk_remove": {
                "type": "pattern_replace",
                "pattern": "(\w+)\*(?=\w)",
                "replacement": ""
              }
            }

注意以下变化:

  • \d => \w(匹配单词字符而不是仅匹配数字)
  • escape * 因为星号对正则表达式有特殊意义
  • 1$ => </code>(<code>$<GROUPNUM> 是您引用捕获组的方式)

要查看 Elasticsearch 如何根据分析器分析文本,或检查您是否正确定义了分析器,Elasticsearch 具有您可以使用的 ANALYZE API 端点:https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-analyze.html

如果您使用您当前定义的 custom_search_analyzer 尝试此 API,您会发现 "MY*ULTRA*TEXT" 被分析为 "MY*ULTRA*TEXT" 而不是 "MYULTRATEXT"你打算。

我有一个个人应用程序,可以更轻松地与 ANALYZE API 的结果进行交互和可视化。我试过你的例子,你可以在这里找到它:Elasticsearch Analysis Inspector.