用elasticsearch搜索特殊字符

时间:2018-08-10 11:21:37

标签: elasticsearch

我只是对Elasticsearch有问题,我有一些需要使用特殊字符进行搜索的业务要求。例如,某些查询字符串可能包含(空格,@,&,^,()、!)。下面有一些类似的用例。

  1. foo&bar123(完全匹配)
  2. foo和bar123(单词之间的空白)
  3. foobar123(无特殊字符)
  4. foobar 123(不带空格的特殊字符)
  5. foo bar 123(单词之间没有空格的特殊字符)
  6. FOO&BAR123(大写)

所有这些都应具有相同的结果,有人可以为此提供一些帮助吗?请注意,现在我可以完美搜索没有特殊字符的其他字符串

{
    "settings": {
        "number_of_shards": 1, 
        "analysis": {
            "analyzer": {
                "autocomplete": {
                    "tokenizer": "custom_tokenizer"
                }
            },
            "tokenizer": {
                "custom_tokenizer": {
                  "type": "ngram",
                  "min_gram": 2,
                  "max_gram": 30,
                  "token_chars": [
                    "letter",
                    "digit"
                  ]
                }
          }
        }
    },
        "mappings": {
            "index": {
                "properties": {
                    "some_field": {
                        "type": "text",
                        "analyzer": "autocomplete"
                    },
                    "some_field_2": {
                        "type": "text",
                        "analyzer": "autocomplete"
                    }
                }
           }
    }
}

1 个答案:

答案 0 :(得分:1)

编辑:

这里有两件事需要检查:

(1)索引文档时是否正在分析特殊字符?

_analyze API告诉我们没有:

POST localhost:9200/index-name/_analyze
{
    "analyzer": "autocomplete",
    "text": "foo&bar"
}

// returns
fo, foo, foob, fooba, foobar, oo, oob, // ...etc: the & has been ignored

这是因为映射中的“ token_chars”:“字母”,“数字”。这两类不包括标点符号,例如“&”。因此,当您将“ foo&bar”上载到索引时,实际上会忽略&。

要在索引中包含&,您想在“ token_chars”列表中包含“标点符号”。您可能还希望将“ symbol”组用于其他一些字符...:

"tokenizer": {
    "custom_tokenizer": {
        "type": "ngram",
            "min_gram": 2,
            "max_gram": 30,
            "token_chars": [
                "letter",
                "digit",
                "symbol",
                "punctuation"
              ]
     }
}

现在我们可以对术语进行适当的分析:

POST localhost:9200/index-name/_analyze
{
    "analyzer": "autocomplete",
    "text": "foo&bar"
}

// returns
fo, foo, foo&, foo&b, foo&ba, foo&bar, oo, oo&, // ...etc

(2)我的搜索查询符合我的期望吗?

现在,我们知道正确地对了“ foo&bar”文档进行了索引(分析),我们需要检查搜索是否返回结果。以下查询有效:

POST localhost:9200/index-name/_doc/_search
{
    "query": {
        "match": { "some_field": "foo&bar" }
    }
}

GET查询http://localhost:9200/index-name/_search?q=foo%26bar

其他查询可能会对结果产生意外的影响-根据the docs,您可能想声明您的search_analyzer与索引分析器(例如ngram索引分析器和标准搜索分析器)不同...但是现在可以了给你