0

我最近发现我不应该在弹性搜索查询中使用通配符。相反,有人告诉我应该使用 ngrams。在我的实验中,这非常有效。我想做的是能够告诉 Elasticsearch 对所有映射字段(或适合特定模式的映射属性)使用 ngram。例如:

CURL -XPUT 'http://localhost:9200/test-ngram-7/' -d '{
     "mappings": {
         "person": {
             "properties": {
                 "name": {
                     "type": "string",
                     "analyzer": "partial"
                 }
             }
         }
     },
     "settings": {
         "analysis": {
             "filter": {
                 "lb_ngram": {
                     "max_gram": 10,
                     "min_gram": 1,
                     "type": "nGram"
                 }
             },
             "analyzer": {
                 "partial": {
                     "filter": [
                         "standard",
                         "lowercase",
                         "asciifolding",
                         "lb_ngram"
                     ],
                     "type": "custom",
                     "tokenizer": "standard"
                 }
             }
         }
     }
 }'

现在,当我添加此映射时:

CURL -XPUT 'http://localhost:9200/test-ngram-7/person/1' -d '{
 "name" : "Cobb",
 "age" : 31
 }'

我可以轻松查询“obb”并获得部分结果。在我的应用程序中,我事先不知道人们将映射哪些领域。我显然可以在客户端将其短路并在发布文档之前声明我的映射,但如果我能做这样的事情会非常酷:

CURL -XPUT 'http://localhost:9200/test-ngram-7/' -d '{
     "mappings": {
         "person": {
             "properties": {
                 "_default_": {
                     "type": "string",
                     "analyzer": "partial"
                 }
             }
         }
     },
     "settings": {
         "analysis": {
             "filter": {
                 "lb_ngram": {
                     "max_gram": 10,
                     "min_gram": 1,
                     "type": "nGram"
                 }
             },
             "analyzer": {
                 "partial": {
                     "filter": [
                         "standard",
                         "lowercase",
                         "asciifolding",
                         "lb_ngram"
                     ],
                     "type": "custom",
                     "tokenizer": "standard"
                 }
             }
         }
     }
 }'

请注意,我使用的是“默认”。如果我能像 "name.*" 那样做也很酷,并且所有以 name 开头的属性都会以这种方式被过滤。我知道弹性搜索支持默认和通配符。*,所以我希望我只是做错了。

简而言之,我希望在自动创建映射时通过 ngram 过滤器运行新属性,而不是使用映射 API。

4

2 回答 2

1

您可以设置一个 dynamic_template,有关信息,请参阅http://www.elasticsearch.org/guide/reference/mapping/root-object-type.html

使用它,您可以根据匹配、模式匹配等为未知字段创建映射模板,并为这些模板应用分析器等。与设置默认分析器相比,这将为您提供更细粒度的行为控制。默认分析器通常应用于“小写”和“asciifolding”等基本内容,但如果您确定要将 nGram 应用于所有字段,它肯定是一种有效的方法。

于 2013-03-12T06:49:03.357 回答
0

所以,我发现的一个解决方案是设置一个“默认”分析器。文档说

默认分析器 分析器以逻辑名称注册。然后可以从映射定义或某些 API 中引用它。如果没有定义,则使用默认值。有一个选项可以定义在无法派生时默认使用哪些分析器。

默认逻辑名称允许配置一个分析器,该分析器将用于索引和搜索 API。default_index 逻辑名可用于配置仅在索引时使用的默认分析器,而 default_search 可用于配置将仅在搜索时使用的默认分析器。

这是一个例子:

CURL -XPUT 'http://localhost:9200/test-ngram-7/' -d '{

     "settings": {
         "analysis": {
             "filter": {
                 "lb_ngram": {
                     "max_gram": 10,
                     "min_gram": 1,
                     "type": "nGram"
                 }
             },
             "analyzer": {
                 "default": {
                     "filter": [
                         "standard",
                         "lowercase",
                         "asciifolding",
                         "lb_ngram"
                     ],
                     "type": "custom",
                     "tokenizer": "standard"
                 }
             }
         }
     }
 }'

然后这个查询将起作用:

CURL -XGET 'http://localhost:9200/test-ngram-7/person/_search' -d '{
  "query":
 {
     "match" : {
         "name" : "obb"
     }
 }
 }'

回答我自己的问题,因为我仍然对这是否是“正确”的方法感兴趣。

于 2013-03-12T03:29:09.363 回答