Elasticsearch - 精确匹配和部分匹配的索引映射设置
Elasticsearch - Index Mapping settings for both exact and partial matching
我是 elasticsearch 的新手,正在尝试学习如何使用最佳映射设置进行索引以实现以下目标。
如果我有这样的文档
{"name":"Galapagos Islands"}
我想得到以下两个查询的结果
1) 部分匹配
{
"query": {
"match": {
"name": "ga"
}
}
}
2) 精确匹配
{
"query": {
"term": {
"name": "Galapagos Islands"
}
}
}
根据我目前的设置。我能够实现部分匹配部分。但是精确匹配returns没有结果。请在下面找到我索引的设置。
{
"mappings": {
"islands": {
"properties": {
"name":{
"type": "string",
"index_analyzer": "autocomplete",
"search_analyzer": "search_ngram"
}
}
}
},
"settings":{
"analysis":{
"analyzer":{
"autocomplete":{
"type":"custom",
"tokenizer":"standard",
"filter":[ "standard", "lowercase", "stop", "kstem", "ngram" ]
},
"search_ngram": {
"type": "custom",
"tokenizer": "keyword",
"filter": "lowercase"
}
},
"filter":{
"ngram":{
"type":"ngram",
"min_gram":2,
"max_gram":15
}
}
}
}
}
对字段进行完全匹配和部分匹配的正确方法是什么?
更新
使用下面给出的设置重新创建索引后。我的映射看起来像这样
curl -XGET 'localhost:9200/testing/_mappings?pretty'
{
"testing" : {
"mappings" : {
"islands" : {
"properties" : {
"name" : {
"type" : "string",
"index_analyzer" : "autocomplete",
"search_analyzer" : "search_ngram",
"fields" : {
"raw" : {
"type" : "string",
"analyzer" : "my_keyword_lowercase_analyzer"
}
}
}
}
}
}
}
}
我的索引设置如下
{
"mappings": {
"islands": {
"properties": {
"name":{
"type": "string",
"index_analyzer": "autocomplete",
"search_analyzer": "search_ngram",
"fields": {
"raw": {
"type": "string",
"analyzer": "my_keyword_lowercase_analyzer"
}
}
}
}
}
},
"settings":{
"analysis":{
"analyzer":{
"autocomplete":{
"type":"custom",
"tokenizer":"standard",
"filter":[ "standard", "lowercase", "stop", "kstem", "ngram" ]
},
"search_ngram": {
"type": "custom",
"tokenizer": "keyword",
"filter": "lowercase"
},
"my_keyword_lowercase_analyzer": {
"type": "custom",
"filter": ["lowercase"],
"tokenizer": "keyword"
}
},
"filter":{
"ngram":{
"type":"ngram",
"min_gram":2,
"max_gram":15
}
}
}
}
}
以上所有内容,当我这样查询时
curl -XGET 'localhost:9200/testing/islands/_search?pretty' -d '{"query": {"term": {"name.raw" : "Galapagos Islands"}}}'
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
我的文档是这个
curl -XGET 'localhost:9200/testing/islands/1?pretty'
{
"_index" : "testing",
"_type" : "islands",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source":{"name":"Galapagos Islands"}
}
向您的 name
属性 添加一个子字段,它应该是 not_analyzed
。或者,如果您关心 lowercase/uppercase,一个 keyword
分词器和一个 lowercase
过滤器。
这应该按原样索引 Galapagos
,而不是修改。然后您可以进行 term
搜索。
例如,keyword
分析器和 lowercase
过滤器:
"my_keyword_lowercase_analyzer": {
"type": "custom",
"filter": [
"lowercase"
],
"tokenizer": "keyword"
}
和映射:
"properties": {
"name":{
"type": "string",
"index_analyzer": "autocomplete",
"search_analyzer": "search_ngram",
"fields": {
"raw": {
"type": "string",
"analyzer": "my_keyword_lowercase_analyzer"
}
}
}
}
要使用的查询是:
{
"query": {
"term": {
"name.raw": "galapagos islands"
}
}
}
因此,您应该使用 name.raw
(子字段)而不是使用相同的字段 - name
。
我是 elasticsearch 的新手,正在尝试学习如何使用最佳映射设置进行索引以实现以下目标。
如果我有这样的文档
{"name":"Galapagos Islands"}
我想得到以下两个查询的结果
1) 部分匹配
{
"query": {
"match": {
"name": "ga"
}
}
}
2) 精确匹配
{
"query": {
"term": {
"name": "Galapagos Islands"
}
}
}
根据我目前的设置。我能够实现部分匹配部分。但是精确匹配returns没有结果。请在下面找到我索引的设置。
{
"mappings": {
"islands": {
"properties": {
"name":{
"type": "string",
"index_analyzer": "autocomplete",
"search_analyzer": "search_ngram"
}
}
}
},
"settings":{
"analysis":{
"analyzer":{
"autocomplete":{
"type":"custom",
"tokenizer":"standard",
"filter":[ "standard", "lowercase", "stop", "kstem", "ngram" ]
},
"search_ngram": {
"type": "custom",
"tokenizer": "keyword",
"filter": "lowercase"
}
},
"filter":{
"ngram":{
"type":"ngram",
"min_gram":2,
"max_gram":15
}
}
}
}
}
对字段进行完全匹配和部分匹配的正确方法是什么?
更新
使用下面给出的设置重新创建索引后。我的映射看起来像这样
curl -XGET 'localhost:9200/testing/_mappings?pretty'
{
"testing" : {
"mappings" : {
"islands" : {
"properties" : {
"name" : {
"type" : "string",
"index_analyzer" : "autocomplete",
"search_analyzer" : "search_ngram",
"fields" : {
"raw" : {
"type" : "string",
"analyzer" : "my_keyword_lowercase_analyzer"
}
}
}
}
}
}
}
}
我的索引设置如下
{
"mappings": {
"islands": {
"properties": {
"name":{
"type": "string",
"index_analyzer": "autocomplete",
"search_analyzer": "search_ngram",
"fields": {
"raw": {
"type": "string",
"analyzer": "my_keyword_lowercase_analyzer"
}
}
}
}
}
},
"settings":{
"analysis":{
"analyzer":{
"autocomplete":{
"type":"custom",
"tokenizer":"standard",
"filter":[ "standard", "lowercase", "stop", "kstem", "ngram" ]
},
"search_ngram": {
"type": "custom",
"tokenizer": "keyword",
"filter": "lowercase"
},
"my_keyword_lowercase_analyzer": {
"type": "custom",
"filter": ["lowercase"],
"tokenizer": "keyword"
}
},
"filter":{
"ngram":{
"type":"ngram",
"min_gram":2,
"max_gram":15
}
}
}
}
}
以上所有内容,当我这样查询时
curl -XGET 'localhost:9200/testing/islands/_search?pretty' -d '{"query": {"term": {"name.raw" : "Galapagos Islands"}}}'
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
我的文档是这个
curl -XGET 'localhost:9200/testing/islands/1?pretty'
{
"_index" : "testing",
"_type" : "islands",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source":{"name":"Galapagos Islands"}
}
向您的 name
属性 添加一个子字段,它应该是 not_analyzed
。或者,如果您关心 lowercase/uppercase,一个 keyword
分词器和一个 lowercase
过滤器。
这应该按原样索引 Galapagos
,而不是修改。然后您可以进行 term
搜索。
例如,keyword
分析器和 lowercase
过滤器:
"my_keyword_lowercase_analyzer": {
"type": "custom",
"filter": [
"lowercase"
],
"tokenizer": "keyword"
}
和映射:
"properties": {
"name":{
"type": "string",
"index_analyzer": "autocomplete",
"search_analyzer": "search_ngram",
"fields": {
"raw": {
"type": "string",
"analyzer": "my_keyword_lowercase_analyzer"
}
}
}
}
要使用的查询是:
{
"query": {
"term": {
"name.raw": "galapagos islands"
}
}
}
因此,您应该使用 name.raw
(子字段)而不是使用相同的字段 - name
。