1. 程式人生 > >【ES】match_phrase與regexp

【ES】match_phrase與regexp

很大的 條件 position 一個 off cnblogs 關系 表達式 color

剛開始接觸es,由於弄不清楚match_phrase和regexp導致很多查詢結果與預想的不同。在這整理一下。

regexp:針對的是單個詞項

match_phrase:針對的是多個詞項的相對位置

它們的查詢結果跟分析器分詞的方式有很大關系。

比如,我有兩個字符串"HELLO-world" 和 "hello.WORLD",字段名稱是title。

針對"HELLO-world",看下面兩個語句。第二個是可以匹配的,第一個不可以。

{ "regexp": { "title": "hello-w.*" }} 
{ "match_phrase": { "title": "hello world
" }}

分析一下,可以看到,HELLO-world被分為了兩個單詞,hello和world。

-GET _analyze
{        
    "field": "title",
    "text": "HELLO-world"
}
---------------------------
{
  "tokens" : [
    {
      "token" : "hello",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position"
: 0 }, { "token" : "world", "start_offset" : 6, "end_offset" : 11, "type" : "<ALPHANUM>", "position" : 1 } ] }

首先,es是沒有大寫的,所有的字符都被轉換成了小寫。其次,"-"字符丟失了。

regexp是針對單個詞項的,無論是hello還是world,都不符合正則條件,故沒有匹配。

match_phrase是針對多個詞項的。首先match_phrase的"hello world"被分為了hello和world兩個單詞,然後這兩個單詞在title的分詞中都可以找到,並且相對位置滿足條件,故語句可以匹配。

再看 "hello.WORLD"

{ "regexp": { "title": "hello\\.w.*" }} 
{ "match_phrase": { "title": "hello world" }}

結果是,第一個可以匹配,而第二個不能。

原因看分詞結果:

-GET_analyze
{        
    "field": "title",
    "text": "hello.WORLD"
}
-------------------------------
{
  "tokens" : [
    {
      "token" : "hello.world",
      "start_offset" : 0,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 0
    }
  ]
}

坑爹的情況出現了,"."並不會被切分,整個"hello.world"被視作了一個詞項。

match_phrase在詞項中查找hello和world都查找不到,故不會匹配

regexp則能找到一個滿足正則表達式的詞項,故可以匹配。

ES的分詞處理非常重要,很大的影響了查詢結果!

【ES】match_phrase與regexp