Add analysis-kuromoji plugin documentation - #12924
Conversation
|
Thank you for submitting your PR. The PR states are In progress (or Draft) -> Tech review -> Doc review -> Merged. Before you submit your PR for doc review, make sure the content is technically accurate. If you need help finding a tech reviewer, tag a maintainer. When you're ready for doc review, tag the assignee of this PR. The doc reviewer may push edits to the PR directly or leave comments and editorial suggestions for you to address (let us know in a comment if you have a preference). |
5d05990 to
1dce0ba
Compare
Signed-off-by: Wojciech Krakowiak <wojciech.krakowiak@ibm.com>
1dce0ba to
331282c
Compare
Signed-off-by: Wojciech Krakowiak <wojciech.krakowiak@ibm.com>
051d6c9 to
bc84c32
Compare
Signed-off-by: Wojciech Krakowiak <wojciech.krakowiak@ibm.com>
|
I fixed all style issues reported by reviewdog that I considered relevant. Remaining ones are treating names or japanese-related terms as options and I consider them false positive. |
|
Thank you, @WojciechKrakowiak! This is great. Trying to find a Japanese-speaking reviewer now. |
|
I will review this from the perspective of a native Japanese speaker. Please wait a moment. |
| ``` | ||
| {% include copy-curl.html %} | ||
|
|
||
| The analyzer uses the custom dictionary rule to segment `東京スカイツリー` into `東京` and `スカイツリー`. The default Katakana stemmer (`kuromoji_stemmer`) then removes the trailing long vowel mark from `スカイツリー` to produce `スカイツリ`, while particles (`に`) and auxiliary verbs (`ました`) are removed, and `行きました` is normalized to its base form `行く`: |
There was a problem hiding this comment.
Kuromoji splits 行きました into three tokens (行き, まし, た), so ました is not a single auxiliary verb. kuromoji_baseform normalizes 行き to 行く, and kuromoji_part_of_speech removes まし and た separately.
|
|
||
| Parameter | Data type | Description | ||
| :--- | :--- | :--- | ||
| `mode` | String | Completion mode. Valid values are `index` (default) and `query`. Use `index` in the index analyzer to generate all reading variants; use `query` in the search analyzer to generate the query-side reading. |
There was a problem hiding this comment.
This reads as if only index mode generates variants. Actually both modes emit variants; query mode additionally merges Kana with trailing lowercase letters (mid-typing IME input, e.g. コンピュ + t → konpyut) so autocomplete matches on in-progress input.
There was a problem hiding this comment.
To clarify my earlier comment: both modes emit Romaji variants when given complete text like コンピューター. The actual difference is how they handle partial IME input like コンピュt (Kana + trailing alphabet from mid-typing): index mode splits it into [コンピュ, t], while query mode merges it as コンピュt → konpyut. This is why the pair is needed — index mode indexes completed text, query mode handles in-progress input. The current description doesn't convey this split.
There was a problem hiding this comment.
That's a good point. I think I have it well described on the kuromoji-completion token filter page, I'll simply reuse the same description.
Controls how tokens are generated. Valid values are `index` (default) and `query`. Both modes expand Katakana tokens into their original form plus all Romaji variants. The `query` mode adds two additional behaviors for handling partial IME input: it concatenates consecutive Kana tokens into a single token before romanizing, and it merges a Kana token with a trailing lowercase alphabet token that represents a partially typed IME keystroke (for example, `サッ` followed by `k` becomes `サッk`).|
|
||
| Compare this with the following [full pipeline example](#example-usage-with-kuromoji_baseform-and-kuromoji_part_of_speech), which uses the same input. Adding `kuromoji_baseform` normalises `学ん` to `学ぶ`, and `kuromoji_part_of_speech` removes `を` and `だ` as grammatical tokens — leaving `ja_stop` to handle `こと`, a common noun that part-of-speech filtering alone would not remove. | ||
|
|
||
| ## Example: Usage with kuromoji_baseform and kuromoji_part_of_speech |
There was a problem hiding this comment.
Ex1 (ja_stop only) and Ex2 (full pipeline) produce nearly identical results on this input — both remove な, こと, を, だ. The only observable difference is 学ん vs 学ぶ (from baseform). The claim "leaving ja_stop to handle こと" doesn't hold in this pairing since Ex1 already removes こと.
There was a problem hiding this comment.
I will provide a better example, in which results differ by number of resulting tokens and a baseform of one token.
The sentence `新聞を読んでいるばかりだ` ("I do nothing but read the newspaper") produces the tokens `新聞`, `を`, `読ん`, `で`, `いる`, `ばかり`, `だ`.
In minimal example:
{
"tokens": [
{
"token": "新聞",
"start_offset": 0,
"end_offset": 2,
"type": "word",
"position": 0
},
{
"token": "読ん",
"start_offset": 3,
"end_offset": 5,
"type": "word",
"position": 2
},
{
"token": "ばかり",
"start_offset": 8,
"end_offset": 11,
"type": "word",
"position": 5
}
]
}
`を`, `で`, `いる`, and `だ` are in the `_japanese_` stop set and are removed.
In pipeline example:
{
"tokens": [
{
"token": "新聞",
"start_offset": 0,
"end_offset": 2,
"type": "word",
"position": 0
},
{
"token": "読む",
"start_offset": 3,
"end_offset": 5,
"type": "word",
"position": 2
}
]
}
- **`kuromoji_baseform`** normalises the inflected verb stem `読ん` to its dictionary form `読む`.
- **`kuromoji_part_of_speech`** removes `ばかり` (adverbial particle) that would not be handled by `ja_stop`, and removes particles `を`, `で`, and `だ` (which would also be removed by `ja_stop`).
- **`ja_stop`** removes remaining `いる`, which is listed in the built-in Japanese stop set.
| } | ||
| ``` | ||
|
|
||
| The past-tense forms 食べて and 飲んだ are replaced with their base forms 食べる and 飲む. The particles を and auxiliary verbs て and だ remain in the token stream because `kuromoji_baseform` only normalizes inflection; it does not remove grammatical tokens. |
There was a problem hiding this comment.
食べて is te-form (a conjunctive form), not past tense — past tense would be 食べた. 飲んだ is past tense. Also て is a conjunctive particle, not an auxiliary verb.
| # Kuromoji completion token filter | ||
|
|
||
| The `kuromoji_completion` token filter is used to stem Katakana words in Japanese, which are often used to represent foreign words or loanwords. This filter is especially useful for autocompletion or suggest queries, in which partial matches on Katakana words can be expanded to include their full forms. | ||
| The `kuromoji_completion` token filter generates romanized reading variants for Katakana tokens. When used in an index analyzer, it emits both the original token and one or more romanized alternatives at the same position. This allows users to search for Japanese content by typing in either Japanese characters or their phonetic equivalents. |
There was a problem hiding this comment.
"Katakana tokens" is inaccurate — Romaji variants are generated for any Japanese token with reading info, not just Katakana. In the example on L89, the Kanji+Hiragana token 使う produces tukau/tsukau.
|
|
||
| Parameter | Data type | Description | ||
| :--- | :--- | :--- | ||
| `mode` | String | Completion mode. Valid values are `index` (default) and `query`. Use `index` in the index analyzer to generate all reading variants; use `query` in the search analyzer to generate the query-side reading. |
There was a problem hiding this comment.
To clarify my earlier comment: both modes emit Romaji variants when given complete text like コンピューター. The actual difference is how they handle partial IME input like コンピュt (Kana + trailing alphabet from mid-typing): index mode splits it into [コンピュ, t], while query mode merges it as コンピュt → konpyut. This is why the pair is needed — index mode indexes completed text, query mode handles in-progress input. The current description doesn't convey this split.
|
|
||
| For the full list of available stoptags, see [stoptags.txt](https://github.com/apache/lucene/blob/main/lucene/analysis/kuromoji/src/resources/org/apache/lucene/analysis/ja/stoptags.txt) in the Lucene source. | ||
|
|
||
| IPAdic tags use a hierarchical structure separated by hyphens. An entry of `助詞` matches all particles, while `助詞-格助詞` matches only case particles. Entries in `stoptags` are treated as prefix matches against the full POS tag. |
There was a problem hiding this comment.
The stoptags matching is exact, not prefix. Lucene's JapanesePartOfSpeechStopFilter uses stopTags.contains(pos) (Set equality). An entry of 助詞 does NOT match 助詞-連体化 or 助詞-格助詞-一般. To remove all particles, every subcategory (助詞, 助詞-格助詞, 助詞-格助詞-一般, ...) must be listed explicitly — this is why the default stoptags.txt enumerates them.
There was a problem hiding this comment.
I'll remove this whole note and update the parameter description.
| ``` | ||
| {% include copy-curl.html %} | ||
|
|
||
| The response shows the particles の (の, genitive), で (location marker), and を (object marker) removed: |
There was a problem hiding this comment.
The (の, ...) looks like a typo — the romanized form was likely intended. Also "location marker" / "object marker" are informal; standard terms are "locative" / "accusative".
|
@WojciechKrakowiak Thank you for well written documentation! I left some comments. |
|
|
||
| The filter applies to tokens that carry dictionary form information from the Kuromoji tokenizer. Tokens without dictionary information (such as unknown words) are passed through unchanged. | ||
|
|
||
| Note that the Kuromoji tokenizer splits some conjugated forms into multiple tokens before this filter runs. For example, the past-tense *i*-adjective 美しかった (was beautiful) is split into 美しかっ and た. The filter normalizes 美しかっ to 美しい, but た remains as a separate token. To remove auxiliary verb tokens like た, add [`kuromoji_part_of_speech`]({{site.url}}{{site.baseurl}}/analyzers/token-filters/kuromoji-part-of-speech/) and [`ja_stop`]({{site.url}}{{site.baseurl}}/analyzers/token-filters/ja-stop/) to the filter chain. |
There was a problem hiding this comment.
This paragraph and L16 make the same point twice — Kuromoji splits inflected forms and kuromoji_baseform normalizes only the stem. Consider consolidating.
|
@lawofcycles thank you for the throughout review! I'll work with it and apply changes :) |
Signed-off-by: Wojciech Krakowiak <wojciech.krakowiak@ibm.com>
Signed-off-by: Wojciech Krakowiak <wojciech.krakowiak@ibm.com>
Signed-off-by: Wojciech Krakowiak <wojciech.krakowiak@ibm.com>
Description
Added quite complete documentation for analysis-kuromoji plugin, that covers analyzer, tokenizer and all token and character filters.
Documentation was created with help of IBM Bob, with analysis of OpenSearch/Lucene/kuromoji source codes. I carefully reviewed generated docs, verifying, testing and fixing nomenclature, every single example and available parameter. I checked translations and verified that I cannot google generated examples or pieces of documentation (to make sure they aren't taken from other websites).
I did my best to verify the content, though I don't speak japan and any additional verification is welcome (though it also may come later from users).
Version
List the OpenSearch version to which this PR applies, e.g. 2.14, 2.12--2.14, or all.
kuromoji-completion analyzer and tokenizer was added in 3.0 (basing on opensearch-project/OpenSearch#4835)
Other components have over 5 years.
Checklist
For more information on following Developer Certificate of Origin and signing off your commits, please check here.