elasticsearch 使用ngram索引的Elasticsearch未找到部分匹配项,elasticsearch,lucene,n-gram,elasticsearch,Lucene,N Gram" /> elasticsearch 使用ngram索引的Elasticsearch未找到部分匹配项,elasticsearch,lucene,n-gram,elasticsearch,Lucene,N Gram" />

elasticsearch 使用ngram索引的Elasticsearch未找到部分匹配项

elasticsearch 使用ngram索引的Elasticsearch未找到部分匹配项,elasticsearch,lucene,n-gram,elasticsearch,Lucene,N Gram,我有一个elasticsearch索引,它是这样创建的: curl -XPUT 'http://localhost:9200/person' -d '{ "settings": { "number_of_shards": 1, "analysis": { "filter": { "autocomplete_filter": { "type": "edge

我有一个elasticsearch索引,它是这样创建的:

curl -XPUT 'http://localhost:9200/person' -d '{
    "settings": {
        "number_of_shards": 1,
        "analysis": {
            "filter": {
                "autocomplete_filter": {
                    "type":     "edge_ngram",
                    "min_gram": 1,
                    "max_gram": 20
                }
            },
            "analyzer": {
                "autocomplete": {
                    "type":      "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase",
                        "autocomplete_filter"
                    ]
                }
            }
        }
    }
}'
在查询名为“ian”的人时,我得到两个结果

curl -XGET http://localhost:9200/person/_search -d '{
        "query": {
                "match": {
                        "_all": "ian"
                }
        }
}’
但在查询字母ia时,我应该得到同样多或更多的结果,但我没有得到任何结果:

curl -XGET http://localhost:9200/person/_search -d '{
        "query": {
                "match": {
                        "_all": "ia"
                }
        }
}’ 
我的edge_ngram过滤器设置有问题吗?我如何解决这个问题

编辑:为了澄清这一点,我希望我的insert语句与下面的内容类似

curl -XPOST "http://localhost:9200/person/RANDOM_STRING HERE/ANOTHER_RANDOM_STRING" -d "{
 "field1" : "value",
 "field2" : "value",
 "field3" : "value"
}"

插入后,我希望对所有字段进行边缘分析,以便我可以按这些字段中的任何一个按部分字符串进行搜索并返回此结果。

除非您为其指定一个标准,否则所有字段将使用默认的analyzer标准。因此_all字段中的标记不是边缘内存。因此,在搜索ia时没有结果。您通常希望避免使用_all字段进行部分匹配搜索,因为它可能会给出意外或令人困惑的结果


如果您仍然需要使用_all字段,则也可以将分析器指定为自动完成。

您没有指定使用分析器的任何类型。所以您定义了分析器,但没有使用它。当您将文档保存为新类型时,映射将被隐式定义,并且将使用,这不会创建部分单词词,因此您对ia的搜索与任何内容都不匹配

处理此问题的一种方法是显式定义类型,并指定要在映射中使用的分析器。以下是一个示例,其中索引名为person like your,类型名为doc,属性名使用分析器进行索引,但不用于搜索:

PUT /person
{
    "settings": {
        "number_of_shards": 1,
        "analysis": {
            "filter": {
                "autocomplete_filter": {
                    "type":     "edge_ngram",
                    "min_gram": 1,
                    "max_gram": 20
                }
            },
            "analyzer": {
                "autocomplete": {
                    "type":      "custom",
                    "tokenizer": "standard",
                    "filter": [
                        "lowercase",
                        "autocomplete_filter"
                    ]
                }
            }
        }
    },
    "mappings": {
        "doc":{
            "properties": {
                "name": {
                    "type": "string",
                    "index_analyzer": "autocomplete",
                    "search_analyzer": "standard"
                }
            }
        }
    }
}
为了测试它,我添加了几个文档:

POST /person/doc/_bulk
{"index":{"_id":1}}
{"name":"Ian"}
{"index":{"_id":2}}
{"name":"Bob Smith"}
然后对名称字段运行匹配查询:

下面是我用来测试一些不同内容的代码,包括使用_all字段使原始查询正常工作:


如果您只想对每种类型和所有属性使用分析器,除非另有指定,那么只需要为索引设置默认分析器。我在ES文档中很难找到这一点,它们并不总是非常友好,但这里有一个例子。我使用的是ES 1.5,但我认为这并不重要

PUT /person
{
   "settings": {
      "number_of_shards": 1,
      "analysis": {
         "filter": {
            "autocomplete_filter": {
               "type": "edge_ngram",
               "min_gram": 1,
               "max_gram": 20
            }
         },
         "analyzer": {
            "default": {
               "type": "custom",
               "tokenizer": "standard",
               "filter": [
                  "lowercase",
                  "autocomplete_filter"
               ]
            }
         }
      }
   }
}
然后我为文档编制了索引并运行了您的查询,结果很好:

POST /person/doc/_bulk
{"index":{"_id":1}}
{"name":"Ian"}
{"index":{"_id":2}}
{"name":"Bob Smith"}

POST /person/_search
{
   "query": {
      "match": {
         "_all": "ia"
      }
   }
}
...
{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1.4142135,
      "hits": [
         {
            "_index": "person",
            "_type": "doc",
            "_id": "1",
            "_score": 1.4142135,
            "_source": {
               "name": "Ian"
            }
         }
      ]
   }
}
代码如下:


你能举个例子吗?我想将所有属性的默认映射设置为索引everythingHmm,问题是它只在类型为doc时起作用,即使这样,它也只在name属性上起作用。我想用它来索引每种类型的每一个属性。请看我的编辑,在那里我给出了一个更具体的例子,说明我希望插入的内容看起来如何。哦,哈哈,那很简单。只需将分析器的名称更改为默认值。我将发布另一个答案来说明这一点。它总是像这样的小东西!非常感谢!非常感谢!你是最棒的
POST /person/doc/_bulk
{"index":{"_id":1}}
{"name":"Ian"}
{"index":{"_id":2}}
{"name":"Bob Smith"}

POST /person/_search
{
   "query": {
      "match": {
         "_all": "ia"
      }
   }
}
...
{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1.4142135,
      "hits": [
         {
            "_index": "person",
            "_type": "doc",
            "_id": "1",
            "_score": 1.4142135,
            "_source": {
               "name": "Ian"
            }
         }
      ]
   }
}