Вы можете написать TokenFilter и использовать его с помощью анализатора. в вашем анализаторе добавить фильтр:
public override TokenStream TokenStream(string fieldName, System.IO.TextReader reader)
{
TokenStream result = BaseAnalyzer.TokenStream(fieldName, reader);
result = new SynonymFilter(result, _languages); // injects synonyms.
return result;
}
Затем в SynonymFilter ввести синонимы в том же положении исходного слова:
private ITermAttribute _termAtt;
private ITypeAttribute _typeAtt;
private IPositionIncrementAttribute _posIncrAtt;
private Queue<string> _synonymTokenQueue = new Queue<string>();
private AttributeSource.State _current = null;
...
public SynonymFilter(TokenStream input)
: base(input)
{
_termAtt = AddAttribute<ITermAttribute>();
_typeAtt = AddAttribute<ITypeAttribute>();
_posIncrAtt = AddAttribute<IPositionIncrementAttribute>();
}
.. .
public override bool IncrementToken()
{
// if our synonymTokens queue contains any tokens, return the next one.
if (_synonymTokenQueue.Count > 0)
{
RestoreState(_current);
_termAtt.SetTermBuffer(_synonymTokenQueue.Dequeue());
_typeAtt.Type = "<SYNONYM>";
_posIncrAtt.PositionIncrement = 0;
return true;
}
try
{
if (!input.IncrementToken()) // EOS; iterator exhausted
{
return false;
}
}
catch (Exception ex)
{
return false;
}
if (!string.IsNullOrEmpty(_termAtt.Term))
{
List<string> synonyms = GetTermSynonyms(_termAtt.Term);
foreach (string synonym in synonyms)
{
_synonymTokenQueue.Enqueue(synonym);
}
}
_current = CaptureState();
return true;
}
примеры кода являются лишь примерами, а не рабочий код, я уверен, что вы можете продолжать здесь ... :)
Омри
Рабочий пример (но без ITypeAttribute) (!): Https://github.com/devhost/Corelicious/blob/master/Corelicious.Lucene/ExpanderFilter.cs – sisve