无法在弹性搜索中搜索带有符号的查询

Unable to search a query with symbols in elasticsearch

我一直在尝试使用 elasticsearch python 客户端 来匹配查询,但我什至无法匹配它在使用转义字符并设置一些自定义分析器并映射它们之后。我想使用 & 进行搜索,但它没有给出任何响应。

from elasticsearch import Elasticsearch

es = Elasticsearch([{'host': 'localhost', 'port': 9200}])


doc1 = {
    'name': 'numb',
    'band': 'linkin_park',
    'year': '2006'
}

doc2 = {
    'name': 'Powerless &',
    'band': 'linkin_park',
    'year': '2006'
}
doc3 = {
    'name': 'Crawling !',
    'band': 'linkin_park',
    'year': '2006'
    }

doc =[doc1, doc2, doc3]
'''
create_index = {
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "type": "custom",
                    "filter": [
                        "lowercase"
                    ],
                    "tokenizer": "whitespace"
                }
            }
        }
    }
}

es.indices.create(index="idx_temp", body=create_index)
'''
for i in range(3):
    es.index(index="idx_temp", doc_type='_doc', id=i, body=doc[i])


my_mapping = {
  "properties": {
      "name": {
          "type": "text",
          "fields": {
              "keyword": {
                  "type": "keyword",
                  'ignore_above': 256
              }
          },
          "analyzer": "my_analyzer"
          "search_analyzer": "my_analyzer"
      },
      "band": {
          "type": "text",
          "fields": {
              "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
              }
          },
          "analyzer": "my_analyzer"
          "search_analyzer": "my_analyzer"
      },
      "year": {
          "type": "text",
          "fields": {
              "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
              }
          },
          "analyzer": "my_analyzer"
          "search_analyzer": "my_analyzer"
      }
  }
}

es.indices.put_mapping(index='idx_temp', body=my_mapping, doc_type='_doc', include_type_name=True)

res = es.search(index='idx_temp', body={
    "query": {
        "match": {
            "name": {
                "query": "powerless &",
                "fuzziness": 3

            }
        }
    }
})

for hit in res['hits']['hits']:
    print(hit['_source'])

预期的输出是 'name': 'Poweeerless &', 但我得到 0 次点击并且没有返回任何值。

我刚刚使用您的索引设置、映射和查询进行了尝试,并且能够得到结果。以下是我所做的 2 件不同的事情。

  1. 转义特殊字符 &,当我尝试直接使用 ES REST API 索引文档时,在邮递员正文下方使用:

{ "content": "Powerless \&" }

然后 ES 给了我 Unrecognized character escape '&' 异常,甚至 Postman,流行的 REST 客户端也警告我字符串不正确。

然后我将上面的有效负载更改为下面并且能够索引文档:

{
    "content": "Powerless \&" :-> Notice I added a another `\` to escape the `&`
}
  1. 我更改了查询以使用相同的字段 ,它的值为 &,在您的情况下它是 name 字段,而不是 content field.,因为匹配查询是 analyzed 并且使用与索引时间相同的分析器。并且能够得到结果。

PS:我还使用 _analyze api 验证了您的分析器,它正在为文本 Powerless \&

生成以下标记
{
    "tokens": [
        {
            "token": "powerless",
            "start_offset": 0,
            "end_offset": 9,
            "type": "word",
            "position": 0
        },
        {
            "token": "\&",
            "start_offset": 10,
            "end_offset": 12,
            "type": "word",
            "position": 1
        }
    ]
}

所以我通过添加另一个字段解决了这个问题

 "search_quote_analyzer": "my_analyzer"

之后的设置字段
"analyzer": "my_analyzer"
"search_analyzer": "my_analyzer"

然后我通过在查询中使用 & 进行搜索来获取我的输出

'name': 'Poweeerless &'