# フレーズ検索時のNGram TokenizerとNGram Token Filterの違いについて

**URL:** <https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409>\
**Category:** 日本語による質問・議論はこちら\
**Created:** [September 5, 2017, 11:24am UTC](https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409 "2017-09-05T11:24:48Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![A.S](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@A.S](https://discuss.elastic.co/u/A.S)\
**Post date:** [September 5, 2017, 11:24am UTC](https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409/1 "2017-09-05T11:24:48Z")

</div>

お世話になっております。

フレーズ検索をした際、アナライザーにNGram Tokenizerをセットした場合と、NGram Token Filterをセットした場合で検索結果が異なりました。  
NGram Token Filterをセットした場合でも、NGram Tokenizerをセットした場合と同じ検索結果にしたいのですが、どなたか解決策をご存じでしょうか。よろしくお願いいたします。

### １．アナライザー設定

```auto
{
  "analysis": {
    "filter": {
      "ngram_filter": {
        "type": "ngram",
        "min_gram": "1",
        "max_gram": "2"
      },
      "normalize": {
        "name": "nfkc",
        "type": "icu_normalizer"
      }
    },
    "char_filter": {
      "whitespace_remove": {
        "pattern": "\\s{1,}",
        "type": "pattern_replace",
        "replacement": ""
      }
    },
    "analyzer": {
      "jp_ngram_tokenizer": {
        "filter": ["normalize"],
        "char_filter": ["whitespace_remove"],
        "type": "custom",
        "tokenizer": "ngram_tokenizer"
      },
      "jp_ngram_filter": {
        "filter": ["normalize", "ngram_filter"],
        "char_filter": ["whitespace_remove"],
        "type": "custom",
        "tokenizer": "whitespace_tokenizer"
      }
    },
    "tokenizer": {
      "ngram_tokenizer": {
        "type": "ngram",
        "min_gram": "1",
        "max_gram": "2"
      },
      "whitespace_tokenizer": { "type": "whitespace" }
    }
  }

```

### ２．登録データ

```auto
value
日本
本日
日の丸弁当
日本国憲法

```

### ３．検索クエリ

(1) NGram Tokenizerの場合

```auto
GET index1/_search
{
  "from": 0,
  "size": 4,
  "query": {
    "match_phrase": {
      "value": {
        "query": "日本",
        "analyzer": "jp_ngram_tokenizer"
      }
    }
  }
}

```

(2) NGram Token Filterの場合

```auto
GET index1/_search
{
  "from": 0,
  "size": 4,
  "query": {
    "match_phrase": {
      "value": {
        "query": "日本",
        "analyzer": "jp_ngram_filter"
      }
    }
  }
}

```

### ４．結果

(1) NGram Tokenizerの場合

```auto
"hits": {
    "total": 2,
    "max_score": 0.8027456,
    "hits": [
      {
        "_index": "index1",        
        "_id": "1",
        "_score": 0.8027456,
        "_source": {
          "value": "日本"
        }
      },
      {
        "_index": "index1",        
        "_id": "4",
        "_score": 0.5158902,
        "_source": {
          "value": "日本国憲法"
        }
      }
    ]
  }

```

(2) NGram Token Filterの場合

```auto
"hits": {
    "total": 4,
    "max_score": 0.27233246,
    "hits": [
      {
        "_index": "index1",        
        "_id": "3",
        "_score": 0.27233246,
        "_source": {
          "value": "日の丸弁当"
        }
      },
      {
        "_index": "index1",        
        "_id": "1",
        "_score": 0.21923064,
        "_source": {
          "value": "日本"
        }
      },
      {
        "_index": "index1",        
        "_id": "2",
        "_score": 0.19454905,
        "_source": {
          "value": "本日"
        }
      },
      {
        "_index": "index1",        
        "_id": "4",
        "_score": 0.17135386,
        "_source": {
          "value": "日本国憲法"
        }
      }
    ]
  }

```

---

<div class="post-metadata">

**Author:** ![johtani](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/johtani/32/44956_2.png) [@johtani](https://discuss.elastic.co/u/johtani)\
**Post date:** [October 3, 2017, 6:24am UTC](https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409/2 "2017-10-03T06:24:53Z")

</div>

根本的な質問として同様にしたい理由というのはどういったものでしょうか？

問題点としては、NGram Token Filterがpositionを書き換えているのが問題になります。。。

---

<div class="post-metadata">

**Author:** ![A.S](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@A.S](https://discuss.elastic.co/u/A.S)\
**Post date:** [October 10, 2017, 3:58am UTC](https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409/3 "2017-10-10T03:58:45Z")

</div>

返信が遅くなってしまい申し訳ございません。  
後出しになってしまいますが、やりたいことは、同義語展開した語でPhrase Matchingをさせるというものです。  
同義語展開がトークンフィルターで行われるため、同じくトークンフィルターでNgramにトークンを分解し、Termの出現位置や順序を保持した状態で検索する必要があると思い、質問させていただきました。  
現状、search\_analyzerクエリを使って検索キーワードの同義語を取得した後に、match\_phraseクエリを組み立てているのですが、よりよい方法はないのでしょうか。

---

<div class="post-metadata">

**Author:** ![johtani](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/johtani/32/44956_2.png) [@johtani](https://discuss.elastic.co/u/johtani)\
**Post date:** [October 10, 2017, 4:45am UTC](https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409/4 "2017-10-10T04:45:16Z")

</div>

Synonymでという話なら、Synonymの設定にTokenizerを指定することができますが、それはダメなのでしょうか？  
[https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-synonym-tokenfilter.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-synonym-tokenfilter.html)

---

<div class="post-metadata">

**Author:** ![A.S](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@A.S](https://discuss.elastic.co/u/A.S)\
**Post date:** [October 10, 2017, 6:10am UTC](https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409/5 "2017-10-10T06:10:21Z")

</div>

ご回答ありがとうございます。  
Synonymの設定のTokenizerですが、Ngramの場合ですと同義語展開できない場合があるため使っていませんでした。

例えば同義語辞書に次の語を登録し、

```auto
にほん => にほん,にっぽん,日本
日本 => 日本,にほん,にっぽん,
日 => 日,日本,にほん,にっぽん

```

Synonymの設定のTokenizerに上記の「ngram\_tokenizer」を設定した場合、  
「にほん」及び「日本」で検索をかけると同義語展開されません。

形態素解析であればSynonymの設定のTokenizerを使うことができると思いますが、Ngramで検索をしたいため困っております。

---

<div class="post-metadata">

**Author:** ![johtani](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/johtani/32/44956_2.png) [@johtani](https://discuss.elastic.co/u/johtani)\
**Post date:** [October 16, 2017, 10:35am UTC](https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409/6 "2017-10-16T10:35:24Z")

</div>

具体的にどのようにやった場合にうまくいかなかったでしょうか？  
実際のサンプルを提示していただけますでしょうか？類義語とNGramの部分だけでもいいので。

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [November 13, 2017, 10:35am UTC](https://discuss.elastic.co/t/ngram-tokenizer-ngram-token-filter/99409/7 "2017-11-13T10:35:31Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
