elasticsearch案例不敏感术语过滤器搜索not_analyzed字段

时间:2015-09-03 22:22:50

标签: elasticsearch case-insensitive

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

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

    应该通过搜索^HELLOWORLD来匹配
  1. ^helloworld,而不是helloworld
  2. #FooBar应与#foobar匹配,但不能与foobar匹配。
  3. Foo Bar应与foo bar匹配,但不能与foobar匹配。
  4. 与我们在此处https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html#_term_filter_with_numbers看到的功能类似,但不区分大小写。

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

    编辑1:

    我的问题的核心似乎是多字段,因为关键字+小写似乎解决了标题中提出的问题。但是,为多字段值属性提出此问题会更准确。

    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" }}}

1 个答案:

答案 0 :(得分:4)

正如您在下面的示例中所看到的,keyword 标记生成器lowercase过滤器正在完成此操作 - 它会保留整个值,同时保留所有空格和特殊字符。可以在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
  } ]
}