protected internal virtual Query GetFieldQuery(String field, String queryText)
{
// Use the analyzer to get all the tokens, and then build a TermQuery,
// PhraseQuery, or nothing based on the term count
TokenStream source;
try
{
source = analyzer.ReusableTokenStream(field, new StringReader(queryText));
source.Reset();
}
catch (IOException)
{
source = analyzer.TokenStream(field, new StringReader(queryText));
}
CachingTokenFilter buffer = new CachingTokenFilter(source);
ITermAttribute termAtt = null;
IPositionIncrementAttribute posIncrAtt = null;
int numTokens = 0;
bool success = false;
try
{
buffer.Reset();
success = true;
}
catch (IOException)
{
// success==false if we hit an exception
}
if (success)
{
if (buffer.HasAttribute<ITermAttribute>())
{
termAtt = buffer.GetAttribute<ITermAttribute>();
}
if (buffer.HasAttribute<IPositionIncrementAttribute>())
{
posIncrAtt = buffer.GetAttribute<IPositionIncrementAttribute>();
}
}
int positionCount = 0;
bool severalTokensAtSamePosition = false;
bool hasMoreTokens = false;
if (termAtt != null)
{
try
{
hasMoreTokens = buffer.IncrementToken();
while (hasMoreTokens)
{
numTokens++;
int positionIncrement = (posIncrAtt != null) ? posIncrAtt.PositionIncrement : 1;
if (positionIncrement != 0)
{
positionCount += positionIncrement;
}
else
{
severalTokensAtSamePosition = true;
}
hasMoreTokens = buffer.IncrementToken();
}
}
catch (IOException)
{
// ignore
}
}
try
{
// rewind the buffer stream
buffer.Reset();
// close original stream - all tokens buffered
source.Close();
}
catch (IOException)
{
// ignore
}
if (numTokens == 0)
return null;
else if (numTokens == 1)
{
String term = null;
try
{
bool hasNext = buffer.IncrementToken();
Debug.Assert(hasNext);
term = termAtt.Term;
}
catch (IOException)
{
// safe to ignore, because we know the number of tokens
}
return NewTermQuery(new Term(field, term));
}
else
{
if (severalTokensAtSamePosition)
{
if (positionCount == 1)
{
// no phrase query:
BooleanQuery q = NewBooleanQuery(true);
for (int i = 0; i < numTokens; i++)
{
String term = null;
try
{
bool hasNext = buffer.IncrementToken();
Debug.Assert(hasNext);
term = termAtt.Term;
}
catch (IOException)
{
// safe to ignore, because we know the number of tokens
}
Query currentQuery = NewTermQuery(
new Term(field, term));
q.Add(currentQuery, Occur.SHOULD);
}
return q;
}
else
{
// phrase query:
MultiPhraseQuery mpq = NewMultiPhraseQuery();
mpq.Slop = phraseSlop;
List<Term> multiTerms = new List<Term>();
int position = -1;
for (int i = 0; i < numTokens; i++)
{
String term = null;
int positionIncrement = 1;
try
{
bool hasNext = buffer.IncrementToken();
Debug.Assert(hasNext == true);
term = termAtt.Term;
if (posIncrAtt != null)
{
positionIncrement = posIncrAtt.PositionIncrement;
}
}
catch (IOException)
{
// safe to ignore, because we know the number of tokens
}
if (positionIncrement > 0 && multiTerms.Count > 0)
{
if (enablePositionIncrements)
{
mpq.Add(multiTerms.ToArray(), position);
}
else
{
mpq.Add(multiTerms.ToArray());
}
multiTerms.Clear();
}
position += positionIncrement;
multiTerms.Add(new Term(field, term));
}
if (enablePositionIncrements)
{
mpq.Add(multiTerms.ToArray(), position);
}
else
{
mpq.Add(multiTerms.ToArray());
}
return mpq;
}
}
else
{
PhraseQuery pq = NewPhraseQuery();
pq.Slop = phraseSlop;
int position = -1;
for (int i = 0; i < numTokens; i++)
{
String term = null;
int positionIncrement = 1;
try
{
bool hasNext = buffer.IncrementToken();
Debug.Assert(hasNext == true);
term = termAtt.Term;
if (posIncrAtt != null)
{
positionIncrement = posIncrAtt.PositionIncrement;
}
}
catch (IOException)
{
// safe to ignore, because we know the number of tokens
}
if (enablePositionIncrements)
{
position += positionIncrement;
pq.Add(new Term(field, term), position);
}
else
{
pq.Add(new Term(field, term));
}
}
return pq;
}
}
}