If you set up an index with token filters like this:
PUT /test_index
POST /test_index/_close
PUT /test_index/_settings
{
"analysis": {
"filter": {
"synonyms": {
"type": "synonym",
"synonyms": [
"one => synonym"
]
},
"word_splitter": {
"type": "word_delimiter_graph",
"preserve_original": true
}
}
}
}
POST /test_index/_open
And then make a request like this:
POST test_index/_analyze
{
"tokenizer": "whitespace",
"filter": [
{
"type": "multiplexer",
"filters": [
"word_splitter, flatten_graph",
"synonyms"
]
}
],
"text": "one/two"
}
The synonym for "one" will get applied to the split token ("one/two" => "one", "two"):
{
"tokens": [
{
"token": "one/two",
"start_offset": 0,
"end_offset": 7,
"type": "word",
"position": 0
},
{
"token": "synonym",
"start_offset": 0,
"end_offset": 3,
"type": "SYNONYM",
"position": 1
},
{
"token": "two",
"start_offset": 4,
"end_offset": 7,
"type": "word",
"position": 2
},
{
"token": "one/two",
"start_offset": 0,
"end_offset": 7,
"type": "word",
"position": 2
}
]
}
I don't understand why this works, since the multiplexer documentation doesn't say anything about the token filter lists interacting.
Though it does say:
Shingle or multi-word synonym token filters will not function normally when they are declared in the filters array because they read ahead internally which is unsupported by the multiplexer
And then later:
The synonym and synonym_graph filters use their preceding analysis chain to parse and analyse their synonym lists, and will throw an exception if that chain contains token filters that produce multiple tokens at the same position. If you want to apply synonyms to a token stream containing a multiplexer, then you should append the synonym filter to each relevant multiplexer filter list, rather than placing it after the multiplexer in the main token chain definition.
So maybe this is just some undefined behavior, and this just happens to work?
Interestingly if I make any of these changes, it stops working (the synonym for "one" doesn't get applied):
{
"word_splitter": {
"type": "word_delimiter_graph",
"preserve_original": false
}
}
But interestingly if I alternatively enable this setting, it also works:
{
"word_splitter": {
"type": "word_delimiter_graph",
"catenate_words": true
}
}
Also weirdly this doesn't work:
{
"synonyms": {
"type": "synonym",
"synonyms": [
"one, synonym"
]
}
}
But this does:
{
"synonyms": {
"type": "synonym",
"synonyms": [
"one, synonym"
],
"catenate_words": false
}
}
And also if I remove the flatten_graph filter from after the word_splitter filter, it stops working:
POST test_index/_analyze
{
"tokenizer": "whitespace",
"filter": [
{
"type": "multiplexer",
"filters": [
"word_splitter",
"synonyms"
]
}
],
"text": "one/two"
}
Since this seems extremely brittle (you have to have three separate things configured in a certain way, and it doesn't really make sense why those would lead to this result), I'm guessing this is just a bug.
The thing is, I'm looking for a way to achieve this result (split tokens with a word_delimiter_graph and then apply synonyms to the results), but there doesn't seem to actually be a supported way of doing this, re this guy's question:
I didn't really even want to use the multiplexer in the first place, it's just that if I try directly applying the synonym filter after the word_delimiter_graph, I get the "Token filter [word_splitter] cannot be used to parse synonyms" error.
So I'm not sure how to proceed - do I just rely on this bug / undefined behavior, or is there a cleaner way of doing this?