如果min_gram设置为1,则在ngram过滤器上突出显示弹性搜索是很奇怪的

con*_*t47 7 elasticsearch

所以我有这个索引

{
  "settings":{
    "index":{
      "number_of_replicas":0,
      "analysis":{
        "analyzer":{
          "default":{
            "type":"custom",
            "tokenizer":"keyword",
            "filter":[
              "lowercase",
              "my_ngram"
            ]
          }
        },
        "filter":{
          "my_ngram":{
            "type":"nGram",
            "min_gram":2,
            "max_gram":20
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

而我正在通过轮胎宝石进行搜索

{
   "query":{
      "query_string":{
         "query":"xyz",
         "default_operator":"AND"
      }
   },
   "sort":[
      {
         "count":"desc"
      }
   ],
   "filter":{
      "term":{
         "active":true,
         "_type":null
      }
   },
   "highlight":{
      "fields":{
         "name":{

         }
      },
      "pre_tags":[
         "<strong>"
      ],
      "post_tags":[
         "</strong>"
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)

我有两个帖子应该匹配名为'xyz post'和'xyz question'当我执行此搜索时,我会正确地返回突出显示的字段

<strong>xyz</strong> question
<strong>xyz</strong> post
Run Code Online (Sandbox Code Playgroud)

现在这就是......只要我在索引中将min_gram更改为1并重新索引.突出显示的字段开始回来了

<strong>x</strong><strong>y</strong><strong>z</strong> pos<strong>xyz</strong>t
<strong>x</strong><strong>y</strong><strong>z</strong> questio<strong>xyz</strong>n
Run Code Online (Sandbox Code Playgroud)

我根本无法理解为什么.

小智 11

简答

您需要检查映射并查看是否使用fast-vector-highlighter.但是你仍然需要对你的查询非常小心.

详细解答

假设使用ES的新实例0.20.4localhost.

在您的示例的基础上,让我们添加显式映射.注意我为该code字段设置了两种不同的分析.唯一的区别是"term_vector":"with_positions_offsets".

curl -X PUT localhost:9200/myindex -d '
{
  "settings" : {
    "index":{
      "number_of_replicas":0,
      "number_of_shards":1,
      "analysis":{
        "analyzer":{
          "default":{
            "type":"custom",
            "tokenizer":"keyword",
            "filter":[
              "lowercase",
              "my_ngram"
            ]
          }
        },
        "filter":{
          "my_ngram":{
            "type":"nGram",
            "min_gram":1,
            "max_gram":20
          }
        }
      }
    }
  },
  "mappings" : {
    "product" : {
      "properties" : {
        "code" : {
          "type" : "multi_field",
          "fields" : {
            "code" : {
              "type" : "string",
              "analyzer" : "default",
              "store" : "yes"
            },
            "code.ngram" : {
              "type" : "string",
              "analyzer" : "default",
              "store" : "yes",
              "term_vector":"with_positions_offsets"
            }
          }
        }
      }
    }
  }
}'
Run Code Online (Sandbox Code Playgroud)

索引一些数据.

curl -X POST 'localhost:9200/myindex/product' -d '{
  "code" : "Samsung Galaxy i7500"
}'

curl -X POST 'localhost:9200/myindex/product' -d '{
  "code" : "Samsung Galaxy 5 Europa"
}'

curl -X POST 'localhost:9200/myindex/product' -d '{
  "code" : "Samsung Galaxy Mini"
}'
Run Code Online (Sandbox Code Playgroud)

现在我们可以运行查询了.

1)搜索"i"以查看一个字符搜索是否与突出显示一起使用

curl -X GET 'localhost:9200/myindex/product/_search?pretty' -d '{
  "fields" : [ "code" ],
  "query" : {
    "term" : {
      "code" : "i"
    }
  },
  "highlight" : {
    "number_of_fragments" : 0,
    "fields" : {
      "code":{},
      "code.ngram":{}
    }
  }
}'
Run Code Online (Sandbox Code Playgroud)

这会产生两个搜索命中:

# 1
...
"fields" : {
  "code" : "Samsung Galaxy Mini"
},
"highlight" : {
  "code.ngram" : [ "Samsung Galaxy M<em>i</em>n<em>i</em>" ],
  "code" : [ "Samsung Galaxy M<em>i</em>n<em>i</em>" ]
}
# 2
...
"fields" : {
  "code" : "Samsung Galaxy i7500"
},
"highlight" : {
  "code.ngram" : [ "Samsung Galaxy <em>i</em>7500" ],
  "code" : [ "Samsung Galaxy <em>i</em>7500" ]
}
Run Code Online (Sandbox Code Playgroud)

这次正确地突出显示了两个codecode.ngem字段.但是当使用更长的查询时,事情会迅速改变:

2)搜索'ym'

curl -X GET 'localhost:9200/myindex/product/_search?pretty' -d '{
  "fields" : [ "code" ],
  "query" : {
    "term" : {
      "code" : "y m"
    }
  },
  "highlight" : {
    "number_of_fragments" : 0,
    "fields" : {
      "code":{},
      "code.ngram":{}
    }
  }
}'
Run Code Online (Sandbox Code Playgroud)

这会产生:

"fields" : {
  "code" : "Samsung Galaxy Mini"
},
"highlight" : {
  "code.ngram" : [ "Samsung Galax<em>y M</em>ini" ],
  "code" : [ "Samsung Galaxy Min<em>y M</em>i" ]
}
Run Code Online (Sandbox Code Playgroud)

code领域是不正确高亮(类似你的情况).

一个重要的是使用术语查询而不是query_string.