我在ES 6.1.1中使用了nGram
标记生成器,并得到了一些奇怪的亮点:
tra
错误地突出显示查询
auftrag
按预期与文档7和9匹配,但是在doc 9中betrag
不正确突出显示。荧光笔存在问题-如果问题出在查询文档8上,则该问题也会被返回。范例程式码
#!/usr/bin/env bash
# Example based on
# https://www.elastic.co/guide/en/elasticsearch/guide/current/ngrams-compound-words.html
# with suggestions from from
# https://github.com/elastic/elasticsearch/issues/21000
如果存在则删除索引
curl -sS -XDELETE 'localhost:9200/my_index'
printf '\n-------------\n'
创建新索引
curl -sS -XPUT 'localhost:9200/my_index?pretty' -H 'Content-Type: application/json' -d'
{
"settings": {
"analysis": {
"analyzer": {
"trigrams": {
"tokenizer": "my_ngram_tokenizer",
"filter": ["lowercase"]
}
},
"tokenizer": {
"my_ngram_tokenizer": {
"type": "nGram",
"min_gram": "3",
"max_gram": "3",
"token_chars": [
"letter",
"digit",
"symbol",
"punctuation"
]
}
}
}
},
"mappings": {
"my_type": {
"properties": {
"text": {
"type": "text",
"analyzer": "trigrams",
"term_vector": "with_positions_offsets"
}
}
}
}
}
'
printf '\n-------------\n'
热门指数
curl -sS -XPOST 'localhost:9200/my_index/my_type/_bulk?pretty' -H 'Content-Type: application/json' -d'
{ "index": { "_id": 7 }}
{ "text": "auftragen" }
{ "index": { "_id": 8 }}
{ "text": "betrag" }
{ "index": { "_id": 9 }}
{ "text": "betrag auftragen" }
'
printf '\n-------------\n'
sleep 1 # Give ES time to index
查询
curl -sS -XGET 'localhost:9200/my_index/my_type/_search?pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"text": {
"query": "auftrag",
"minimum_should_match": "100%"
}
}
},
"highlight": {
"fields": {
"text": {
"fragment_size": 120,
"type": "fvh"
}
}
}
}
'
我得到的点击数是(缩写):
"hits" : [
{
"_id" : "9",
"_source" : {
"text" : "betrag auftragen"
},
"highlight" : {
"text" : [
"be<em>tra</em>g <em>auf</em><em>tra</em>gen"
]
}
},
{
"_id" : "7",
"_source" : {
"text" : "auftragen"
},
"highlight" : {
"text" : [
"<em>auf</em><em>tra</em>gen"
]
}
}
]
我尝试了各种变通办法,例如使用Unified / FVH荧光笔并设置所有似乎相关但没有运气的选项。任何提示,不胜感激。
最佳答案
这里的问题不是突出显示,而是您使用nGram分析器的方式。
首先,当您以这种方式配置映射时:
"mappings": {
"my_type": {
"properties": {
"text": {
"type" : "text",
"analyzer" : "trigrams",
"term_vector": "with_positions_offsets"
}
}
}
}
您在对Elasticsearch说您想将其用于索引文本并提供搜索词。就您而言,这仅意味着:
首先,您需要对Elasticsearch说,您不想将搜索字词拆分为g。您需要做的就是将
search_analyzer
属性添加到映射中:"mappings": {
"my_type": {
"properties": {
"text": {
"type" : "text",
"analyzer" : "trigrams",
"search_analyzer": "standard",
"term_vector" : "with_positions_offsets"
}
}
}
}
现在
standard
analyzer将搜索词中的单词视为单独的单词,因此在您的情况下,它将只是“auftrag”。但是,这一单一更改将无济于事。甚至会中断搜索,因为“auftrag”与您索引中的任何三字组都不匹配。
现在,您需要通过增加
max_gram
来改进nGram标记器:"tokenizer": {
"my_ngram_tokenizer": {
"type": "nGram",
"min_gram": "3",
"max_gram": "10",
"token_chars": [
"letter",
"digit",
"symbol",
"punctuation"
]
}
}
这样,索引中的文本将分为3克,4克,5克,6克,7克,8克,9克和10克。在这7克中,您会找到“auftrag”(搜索词)。
经过这两项改进后,搜索结果中的突出显示应如下所示:
"betrag <em>auftrag</em>en"
对于文件9和:
"<em>auftrag</em>en"
用于文件7。
这就是ngram和突出显示一起工作的方式。我知道ES documentation is saying:
这是真的。出于性能原因,您需要尝试此配置,但是希望我向您解释了它是如何工作的。