not_analyzed 字段上的 elasticsearch 不区分大小写的术语过滤器搜索

elasticsearch case insensitive term filter search on not_analyzed field

这里有类似的问题Elasticsearch Map case insensitive to not_analyzed documents,但我的问题略有不同,因为我处理的是特殊字符。

大多数人建议结合使用 keyword analyzerlowercase filter。但是,这对我的情况不起作用,因为关键字分析器对空格和 ^, #, etc 等特殊字符进行标记。这打破了我想要的支持类型。

  1. ^HELLOWORLD应该通过搜索^helloworld来匹配,而不是helloworld
  2. #FooBar 应该匹配 #foobar 而不是 foobar.
  3. Foo Bar 应与 foo bar 匹配,而不是 foobar.

与我们在此处看到的功能类似 https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html#_term_filter_with_numbers,但不区分大小写。

有谁知道如何做到这一点?

编辑 1:

看来我的问题的核心是multi-field,因为关键字+小写似乎解决了标题中提出的问题。但是,针对 multi-field 值 属性.

提出这个问题会更准确

test_mapping.json:

{
  "properties" : {
    "productID1" : {
      "type" : "string",
      "index_analyzer" :  "keyword_lowercase",
      "search_analyzer" : "keyword_lowercase"
    },
    "productID2" : {
      "type": "multi_field",
      "keyword_edge_ID": {
        "type": "string", 
        "index_analyzer":"keyword_lowercase_edge", 
        "search_analyzer":"keyword_lowercase_edge"
      },
      "productID2": {
        "type": "string", 
        "index": "analyzed", 
        "store": "yes", 
        "index_analyzer":"keyword_lowercase", 
        "search_analyzer":"keyword_lowercase"
      }
    }
  }
}

test.json:

{
  "index": {
    "analysis": {
      "filter":{
        "edgengramfilter": {
          "type": "edgeNgram",
          "side": "front",
          "min_gram": 1,
          "max_gram": 32
        }
      },
      "analyzer": {
        "keyword_lowercase" : {
          "type" : "custom",
          "tokenizer": "keyword",
          "filter": "lowercase"
        },
        "keyword_lowercase_edge": {
            "tokenizer": "keyword",
            "filter": ["lowercase", "edgengramfilter"]
        }
      }
    }
  }
}

Shell 使用映射创建索引的脚本:

#!/bin/sh

ES_URL="http://localhost:9200"

curl -XDELETE $ES_URL/test
curl -XPOST $ES_URL/test/ --data-binary @test.json
curl -XPOST $ES_URL/test/query/_mapping --data-binary @test_mapping.json

POST localhost:9200/test/query:

{ 
  "productID1" : "^A",
  "productID2" : "^A" 
}

我想要它,以便我可以用“^A”匹配 productID2,但它现在没有返回任何结果,但是当我对 productID1 执行相同的查询时它有效。 {"query": { "match": { "productID2": "^A" }}}

正如您在下面的示例中看到的那样,keyword tokenizerlowercase 过滤器正是这样做的 - 它在保留的同时将整个值小写所有空格和特殊字符。如何使用它的例子可以在 this answer.

中找到
curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "^HELLOWORLD"
{
  "tokens" : [ {
    "token" : "^helloworld",
    "start_offset" : 0,
    "end_offset" : 11,
    "type" : "word",
    "position" : 1
  } ]
}

curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "#FooBar"    
{
  "tokens" : [ {
    "token" : "#foobar",
    "start_offset" : 0,
    "end_offset" : 7,
    "type" : "word",
    "position" : 1
  } ]
}

curl "localhost:9200/_analyze?pretty&tokenizer=keyword&filters=lowercase" -d "Foo Bar"
{
  "tokens" : [ {
    "token" : "foo bar",
    "start_offset" : 0,
    "end_offset" : 7,
    "type" : "word",
    "position" : 1
  } ]
}