我最近发现我不应该使用通配符进行弹性搜索查询。相反,我被告知我应该使用ngrams。在我的实验中,这非常有效。我想做的是能够告诉Elasticsearch对所有映射字段(或适合特定模式的映射属性)使用ngrams。 例如:
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开头的属性都会以这种方式过滤。我知道elasticsearch支持默认和通配符。*,所以我希望我做错了。
简而言之,我希望新的属性能够在自动创建映射时运行ngram过滤器,而不是使用映射API。
答案 0 :(得分:1)
您可以设置dynamic_template,有关信息,请参阅http://www.elasticsearch.org/guide/reference/mapping/root-object-type.html。
使用此功能,您可以根据匹配,模式匹配等为您未知的字段创建映射模板,并为这些模板应用分析器等。与设置默认分析器相比,这将为您提供更细粒度的行为控制。默认分析器通常应该用于“小写”和“asciifolding”之类的基本内容,但如果您确定要将nGram应用于所有字段,那么它肯定是一种有效的方法。
答案 1 :(得分: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"
}
}
}'
回答我自己的问题,因为我仍然感兴趣,如果这是“正确”的方式来做到这一点。