1

我有一个应该搜索小写字词的查询。

实际上,我只有一个带有小写过滤器的index_analyzer,但我还想添加一个search_analyzer,这样我就可以进行不区分大小写的搜索。

"analysis": {
    "analyzer" : {
        "DefaultAnalyzer": {
            "type": "custom",
            "tokenizer": "whitespace",
            "filter": [
                "lowercase"
            ],
            "char_filter": ["punctuation"]
        },
        "MyAnalyzer": {
            "type": "custom",
            "tokenizer": "first_letter",
            "filter": [
                "lowercase"
            ]
        },

所以我只是想将与search_analyzer相同的分析器添加到映射中

"index_analyzer": "DefaultAnalyzer",
"search_analyzer": "DefaultAnalyzer",
"dynamic" : false,
"_source": { "enabled": true },
"properties" : {
    "name": {
        "type": "multi_field",
        "fields": {
            "name": {
                "type": "string",
                "store": true
            },
            "startletter": {
                "type": "string",
                "index_analyzer": "MyAnalyzer",
                "search_analyzer": "MyAnalyzer",
                "store": true
            }
        }
    },

这样做,如果我手动查询弹性搜索

curl -XGET host:9200/my-index/_analyze -d 'Test'

我看到查询词是正确小写的

{
  "tokens": [
    {
      "token": "test",
      "start_offset": 0,
      "end_offset": 4,
      "type": "<ALPHANUM>",
      "position": 1
    }
  ]
}

但是从代码执行

  • 如果我使用大写搜索词 ES 返回零命中(即使我们看到应用了search_analyzer
  • 如果我使用小写搜索词 ES 返回我正确的结果命中数(数百)

虽然我想独立于案例获得相同的结果。

在代码中,我只是创建一个带有术语过滤器的查询,就像这样

{
  "filter": {
    "term": {
      "name.startletter": "O"
    }
  },
  "size": 10000,
  "query": {
    "match_all": {}
  }
}

我做错了什么?为什么我没有得到任何结果?

4

2 回答 2

4

问题是您正在使用术语过滤器。术语过滤器不分析正在使用的文本:

词条过滤器

过滤具有包含术语(未分析)的字段的文档。类似于术语查询,只是它充当过滤器。

http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html

由于它不进行分析,因此它不使用您定义的分析器。

您通常希望对未分析的字段使用术语过滤器和查询。将您的过滤器类型更改为将在查询期间分析的内容。

于 2014-08-06T22:04:19.520 回答
1

我认为,您正在使用 MyAnalyzer 来获取索引的起始字母,您的分析器不能以这种方式工作。我做了一些测试,最后想出了解决方案。

一、创建索引和映射(+设置)

curl -XPUT "http://localhost:9200/t1" -d'
{
   "settings": {
      "index": {
         "analysis": {
            "analyzer": {
               "DefaultAnalyzer": {
                  "type": "custom",
                  "tokenizer": "whitespace",
                  "filter": [
                     "lowercase"
                  ]
               },
               "MyAnalyzer": {
                  "type": "custom",
                  "tokenizer": "token_letter",
                  "filter": [
                     "one_token","lowercase"
                  ]
               }
            },
            "tokenizer": {
               "token_letter": {
                  "type": "edgeNGram",
                  "min_gram": "1",
                  "max_gram": "1",
                  "token_chars": [
                     "letter",
                     "digit"
                  ]
               }
            },
            "filter": {
               "one_token": {
                  "type": "limit",
                  "max_token_count": 1
               }
            }
         }
      }
   },
   "mappings": {
      "t2": {
         "index_analyzer": "DefaultAnalyzer",
         "search_analyzer": "DefaultAnalyzer",
         "dynamic": false,
         "_source": {
            "enabled": true
         },
         "properties": {
            "name": {
               "type": "multi_field",
               "fields": {
                  "name": {
                     "type": "string",
                     "store": true
                  },
                  "startletter": {
                     "type": "string",
                     "index_analyzer": "MyAnalyzer",
                     "search_analyzer": "simple",
                     "store": true
                  }
               }
            }
         }
      }
   }
}'

而且,现在写一个数据。

curl -XPUT "http://localhost:9200/t1/t2/1" -d'
{
    "name" :"Oliver Khan"
}'

现在,这是有趣的部分,只是一个查询和分面来查看索引的内容。

curl -XPOST "http://localhost:9200/t1/t2/_search" -d'
{
  "filter": {
    "term": {
      "name.startletter": "O"
    }
  },
  "size": 10000,
  "query": {
    "match_all": {}
  },
  "facets": {
     "tf": {
        "terms": {
           "field": "name.startletter",
           "size": 10
        }
     }
  }
}'

这给了我分析的文本,作为方面的输出,所以我可以检查分析器是否工作。希望这可以帮助!!

于 2014-08-06T16:15:49.300 回答